summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-09-29 17:32:26 +0100
committerSteve Block <steveblock@google.com>2010-09-29 17:35:08 +0100
commit68513a70bcd92384395513322f1b801e7bf9c729 (patch)
tree161b50f75a5921d61731bb25e730005994fcec85 /JavaScriptCore
parentfd5c6425ce58eb75211be7718d5dee960842a37e (diff)
downloadexternal_webkit-68513a70bcd92384395513322f1b801e7bf9c729.zip
external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.gz
external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.bz2
Merge WebKit at r67908: Initial merge by Git
Change-Id: I43a553e7b3299b28cb6ee8aa035ed70fe342b972
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/ChangeLog480
-rw-r--r--JavaScriptCore/Configurations/FeatureDefines.xcconfig3
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptCore/JavaScriptCore.exp8
-rw-r--r--JavaScriptCore/JavaScriptCore.pro32
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make2
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def4
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make1
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj8
-rw-r--r--JavaScriptCore/parser/ASTBuilder.h1
-rw-r--r--JavaScriptCore/parser/JSParser.cpp134
-rw-r--r--JavaScriptCore/parser/JSParser.h3
-rw-r--r--JavaScriptCore/parser/Nodes.cpp31
-rw-r--r--JavaScriptCore/parser/Nodes.h22
-rw-r--r--JavaScriptCore/parser/Parser.cpp7
-rw-r--r--JavaScriptCore/parser/Parser.h25
-rw-r--r--JavaScriptCore/parser/SyntaxChecker.h1
-rw-r--r--JavaScriptCore/runtime/Collector.cpp4
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp43
-rw-r--r--JavaScriptCore/runtime/Executable.cpp24
-rw-r--r--JavaScriptCore/runtime/Executable.h6
-rw-r--r--JavaScriptCore/runtime/GCActivityCallbackCF.cpp6
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp9
-rw-r--r--JavaScriptCore/runtime/JSValue.cpp63
-rw-r--r--JavaScriptCore/runtime/JSValue.h88
-rw-r--r--JavaScriptCore/runtime/MemoryStatistics.cpp55
-rw-r--r--JavaScriptCore/runtime/MemoryStatistics.h46
-rw-r--r--JavaScriptCore/runtime/RegExpObject.h2
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp3
-rw-r--r--JavaScriptCore/wtf/OwnPtrCommon.h4
-rw-r--r--JavaScriptCore/wtf/Platform.h6
-rw-r--r--JavaScriptCore/wtf/PlatformRefPtr.h5
-rw-r--r--JavaScriptCore/wtf/TypeTraits.cpp5
-rw-r--r--JavaScriptCore/wtf/TypeTraits.h12
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.h9
-rw-r--r--JavaScriptCore/wtf/brew/OwnPtrBrew.cpp14
-rw-r--r--JavaScriptCore/wtf/gobject/GTypedefs.h2
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.cpp6
-rw-r--r--JavaScriptCore/wtf/text/WTFString.h41
-rw-r--r--JavaScriptCore/wtf/unicode/Unicode.h2
-rw-r--r--JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h (renamed from JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h)1
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h45
-rw-r--r--JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp (renamed from JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp)2
-rw-r--r--JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h (renamed from JavaScriptCore/wtf/unicode/wince/UnicodeWince.h)51
-rw-r--r--JavaScriptCore/wtf/wince/FastMallocWinCE.h (renamed from JavaScriptCore/wtf/wince/FastMallocWince.h)7
-rw-r--r--JavaScriptCore/wtf/wtf.pri35
-rw-r--r--JavaScriptCore/yarr/RegexCompiler.cpp95
-rw-r--r--JavaScriptCore/yarr/RegexJIT.cpp182
-rw-r--r--JavaScriptCore/yarr/RegexPattern.h31
49 files changed, 1231 insertions, 437 deletions
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 85860d8..045347a 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,483 @@
+2010-09-20 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fixed detection of alternative smaller than the first alternative
+ to only check looping alternatives.
+ https://bugs.webkit.org/show_bug.cgi?id=46049
+
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateDisjunction):
+
+2010-09-20 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Geoffrey Garen.
+
+ REGRESSION(67790): jsc tests are failed with YARR interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=46083
+
+ Fix the initializing of the lastSubpatternId member of
+ parentheses.
+
+ * yarr/RegexCompiler.cpp:
+ (JSC::Yarr::RegexPatternConstructor::atomParenthesesEnd):
+
+2010-09-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 46077 - ASSERT failure in YARR JIT
+
+ We will currently attempt to loop if there are multiple alternatives, they are all
+ BOL predicated, and the last alternative is longer then the first - however if all
+ alternatives are BOL predicated the head of loop label will not have been set, and
+ we'll try to link a jump to an undefined label. Stop doing so.
+
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateDisjunction):
+
+2010-09-20 Adam Roben <aroben@apple.com>
+
+ Export RegExpObject::info from JavaScriptCore
+
+ This allows obj->inherits(&RegExpObject::info) to work correctly from
+ outside JavaScriptCore.dll on Windows.
+
+ Fixes <http://webkit.org/b/46098>
+ fast/loader/stateobjects/pushstate-object-types.html fails on Windows
+
+ Reviewed by John Sullivan.
+
+ * runtime/RegExpObject.h: Added JS_EXPORTDATA to the info member, as
+ we already have for some other classes whose info members have to be
+ used from outside the DLL.
+
+2010-09-19 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix pt 2.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-09-19 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix pt 1.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-09-19 Gavin Barraclough <barraclough@apple.com>
+
+ Build fix - implicit double-to-int conversion invalid on 32-bit.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::fillStructuresUsingDateArgs):
+ (JSC::dateProtoFuncSetYear):
+
+2010-09-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 46065 - Unify implementation of ToInt32 and ToUInt32, don't use fmod.
+
+ These methods implement the same conversion (see discussion in the notes
+ of sections of 9.5 and 9.6 of the spec), only differing in how the result
+ is interpretted.
+
+ Date prototype is incorrectly using toInt32, and this is causing us to
+ provide an output value indicating whether the input to ToInt32 was finite
+ (the corresponding methods on Date are actually spec'ed to use ToInteger,
+ not ToInt32). This patch partially fixes this in order to remove this
+ bogus output value, hoewever more work will be require to bring Date
+ fully up to spec compliance (the constructor is still performing ToInt32
+ conversions).
+
+ * JavaScriptCore.exp:
+ * runtime/DatePrototype.cpp:
+ (JSC::fillStructuresUsingTimeArgs):
+ (JSC::fillStructuresUsingDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ * runtime/JSValue.cpp:
+ (JSC::toInt32):
+ * runtime/JSValue.h:
+ (JSC::toUInt32):
+ (JSC::JSValue::toInt32):
+ (JSC::JSValue::toUInt32):
+
+2010-09-18 Darin Adler <darin@apple.com>
+
+ First step in fixing Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ Removed incorrect symbol. The build will probably still fail,
+ but the failure will tell us what symbol to add.
+
+2010-09-18 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Added code to unroll regular expressions containing ^.
+ Alternatives that begin with ^ are tagged during parsing
+ and rolled up in containing sub expression structs.
+ After parsing, a regular expression flagged as containing
+ a ^ (a.k.a. BOL) is processed further in optimizeBOL().
+ A copy of the disjunction is made excluding alternatives that
+ are rooted with BOL. The original alternatives are flagged
+ to only be executed once. The copy of the other alternatives are
+ added to the original expression.
+ In the case that all original alternatives are flagged, there
+ won't be any looping alternatives.
+ The JIT generator will emit code accordingly, executing the
+ original alternatives once and then looping over the
+ alternatives that aren't anchored with a BOL (if any).
+ https://bugs.webkit.org/show_bug.cgi?id=45787
+
+ * yarr/RegexCompiler.cpp:
+ (JSC::Yarr::RegexPatternConstructor::assertionBOL):
+ (JSC::Yarr::RegexPatternConstructor::atomParenthesesEnd):
+ (JSC::Yarr::RegexPatternConstructor::copyDisjunction):
+ (JSC::Yarr::RegexPatternConstructor::copyTerm):
+ (JSC::Yarr::RegexPatternConstructor::optimizeBOL):
+ (JSC::Yarr::compileRegex):
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateDisjunction):
+ * yarr/RegexPattern.h:
+ (JSC::Yarr::PatternAlternative::PatternAlternative):
+ (JSC::Yarr::PatternAlternative::setOnceThrough):
+ (JSC::Yarr::PatternAlternative::onceThrough):
+ (JSC::Yarr::PatternDisjunction::PatternDisjunction):
+ (JSC::Yarr::RegexPattern::RegexPattern):
+ (JSC::Yarr::RegexPattern::reset):
+
+2010-09-18 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Rename Wince files to WinCE
+ https://bugs.webkit.org/show_bug.cgi?id=37287
+
+ * wtf/unicode/Unicode.h:
+ * wtf/unicode/wince/UnicodeWinCE.cpp: Copied from JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp.
+ * wtf/unicode/wince/UnicodeWinCE.h: Copied from JavaScriptCore/wtf/unicode/wince/UnicodeWince.h.
+ * wtf/unicode/wince/UnicodeWince.cpp: Removed.
+ * wtf/unicode/wince/UnicodeWince.h: Removed.
+ * wtf/wince/FastMallocWinCE.h: Copied from JavaScriptCore/wtf/wince/FastMallocWince.h.
+ * wtf/wince/FastMallocWince.h: Removed.
+
+2010-09-18 Ademar de Souza Reis Jr <ademar.reis@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Enable Platform Strategies on Qt
+
+ [Qt] Turn on PLATFORM_STRATEGIES
+ https://bugs.webkit.org/show_bug.cgi?id=45831
+
+ * wtf/Platform.h: Enable Platform Strategies when building QtWebkit
+
+2010-09-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Imprecise tracking of variable capture leads to overly pessimistic creation of activations
+ https://bugs.webkit.org/show_bug.cgi?id=46020
+
+ The old logic for track free and captured variables would cause us
+ to decide we needed an activation in every function along the scope
+ chain between a variable capture and its declaration. We now track
+ captured variables precisely which requires a bit of additional work
+
+ The most substantial change is that the parsing routine needs to
+ be passed the list of function parameters when reparsing a function
+ as when reparsing we don't parse the function declaration itself only
+ its body.
+
+ * JavaScriptCore.exp:
+ * parser/JSParser.cpp:
+ (JSC::JSParser::Scope::Scope):
+ (JSC::JSParser::Scope::needsFullActivation):
+ We need to distinguish between use of a feature that requires
+ an activation and eval so we now get this additional flag.
+ (JSC::JSParser::Scope::collectFreeVariables):
+ (JSC::JSParser::Scope::getCapturedVariables):
+ We can't simply return the list of "capturedVariables" now as
+ is insufficiently precise, so we compute them instead.
+ (JSC::JSParser::popScope):
+ (JSC::jsParse):
+ (JSC::JSParser::JSParser):
+ (JSC::JSParser::parseProgram):
+ (JSC::JSParser::parseWithStatement):
+ (JSC::JSParser::parseTryStatement):
+ (JSC::JSParser::parseFunctionInfo):
+ (JSC::JSParser::parseFunctionDeclaration):
+ (JSC::JSParser::parseProperty):
+ (JSC::JSParser::parseMemberExpression):
+ * parser/JSParser.h:
+ * parser/Parser.cpp:
+ (JSC::Parser::parse):
+ * parser/Parser.h:
+ (JSC::Parser::parse):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::checkSyntax):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ (JSC::FunctionExecutable::reparseExceptionInfo):
+ (JSC::EvalExecutable::reparseExceptionInfo):
+ (JSC::FunctionExecutable::fromGlobalCode):
+ Pass function parameters (if available) to the parser.
+
+2010-09-17 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Add IsFloatingPoint and IsArithmetic type traits
+ https://bugs.webkit.org/show_bug.cgi?id=46018
+
+ * wtf/TypeTraits.h:
+ * wtf/TypeTraits.cpp:
+
+2010-09-17 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Oliver Hunt.
+
+ [GTK] FontPlatformDataFreeType should use smart pointers to hold its members
+ https://bugs.webkit.org/show_bug.cgi?id=45917
+
+ Added support to PlatformRefPtr for handling HashTableDeletedValue.
+
+ * wtf/PlatformRefPtr.h:
+ (WTF::PlatformRefPtr::PlatformRefPtr): Added a constructor that takes HashTableDeletedValue.
+ (WTF::PlatformRefPtr::isHashTableDeletedValue): Added.
+
+2010-09-16 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Crash due to timer triggered GC on one heap while another heap is active
+ https://bugs.webkit.org/show_bug.cgi?id=45932
+ <rdar://problem/8318446>
+
+ The GC timer may trigger for one heap while another heap is active. This
+ is safe, but requires us to ensure that we have temporarily associated the
+ thread's identifierTable with the heap we're collecting on. Otherwise we
+ may end up with the identifier tables in an inconsistent state leading to
+ an eventual crash.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::allocate):
+ (JSC::Heap::reset):
+ (JSC::Heap::collectAllGarbage):
+ Add assertions to ensure we have the correct identifierTable active
+ while collecting.
+ * runtime/GCActivityCallbackCF.cpp:
+ (JSC::DefaultGCActivityCallbackPlatformData::trigger):
+ Temporarily make the expected IdentifierTable active
+ * wtf/WTFThreadData.h:
+ (JSC::IdentifierTable::remove):
+ Make it possible to see when IdentifierTable::remove has succeeded
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::~StringImpl):
+ CRASH if an StringImpl is an Identifier but isn't present in the
+ active IdentifierTable. If we get to this state something has
+ gone wrong and we should just crash immediately.
+
+2010-09-16 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Implement dissolveDragImageToFraction
+ https://bugs.webkit.org/show_bug.cgi?id=45826
+
+ * wtf/gobject/GTypedefs.h: Added forward declarations for GtkWindow and GdkEventExpose.
+
+2010-09-16 Eric Uhrhane <ericu@chromium.org>
+
+ Reviewed by Jian Li.
+
+ Unify FILE_SYSTEM and FILE_WRITER enables under the name FILE_SYSTEM.
+ https://bugs.webkit.org/show_bug.cgi?id=45798
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-09-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Use free variable analysis to improve activation performance
+ https://bugs.webkit.org/show_bug.cgi?id=45837
+
+ Adds free and captured variable tracking to the JS parser. This
+ allows us to avoid construction of an activation object in some
+ cases. Future patches will make more use of this information to
+ improve those cases where activations are still needed.
+
+ * parser/ASTBuilder.h:
+ * parser/JSParser.cpp:
+ (JSC::JSParser::Scope::Scope):
+ (JSC::JSParser::Scope::declareVariable):
+ (JSC::JSParser::Scope::useVariable):
+ (JSC::JSParser::Scope::collectFreeVariables):
+ (JSC::JSParser::Scope::capturedVariables):
+ (JSC::JSParser::ScopeRef::ScopeRef):
+ (JSC::JSParser::ScopeRef::operator->):
+ (JSC::JSParser::ScopeRef::index):
+ (JSC::JSParser::currentScope):
+ (JSC::JSParser::pushScope):
+ (JSC::JSParser::popScope):
+ (JSC::JSParser::parseProgram):
+ (JSC::JSParser::parseVarDeclarationList):
+ (JSC::JSParser::parseConstDeclarationList):
+ (JSC::JSParser::parseTryStatement):
+ (JSC::JSParser::parseFormalParameters):
+ (JSC::JSParser::parseFunctionInfo):
+ (JSC::JSParser::parseFunctionDeclaration):
+ (JSC::JSParser::parsePrimaryExpression):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNodeData::ScopeNodeData):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::needsActivation):
+ (JSC::ScopeNode::hasCapturedVariables):
+ * parser/Parser.cpp:
+ (JSC::Parser::didFinishParsing):
+ * parser/Parser.h:
+ (JSC::Parser::parse):
+ * parser/SyntaxChecker.h:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::needsActivation):
+ (JSC::ScriptExecutable::recordParse):
+
+2010-09-14 Hyung Song <beergun@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Add IMemGroup and IMemSpace to OwnPtr type.
+ https://bugs.webkit.org/show_bug.cgi?id=44764
+
+ * wtf/OwnPtrCommon.h:
+ * wtf/brew/OwnPtrBrew.cpp:
+ (WTF::deleteOwnedPtr):
+
+2010-09-14 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Sort with non-numeric custom sort function fails on array with length but no values
+ https://bugs.webkit.org/show_bug.cgi?id=45781
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::sort): Replaced early exit for an array of length zero to instead
+ exit for any array without values, even if it has a non-0 length.
+
+2010-09-14 Steve Falkenburg <sfalken@apple.com>
+
+ Windows production build fix.
+ Roll out r65143.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
+
+2010-09-14 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Darin Adler.
+
+ Share UnicodeMacrosFromICU.h
+ https://bugs.webkit.org/show_bug.cgi?id=45710
+
+ glib, qt4 and wince use the same macros from ICU.
+ Remove the code duplication and use the same header file.
+
+ * wtf/unicode/UnicodeMacrosFromICU.h: Copied from JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h.
+ * wtf/unicode/glib/UnicodeMacrosFromICU.h: Removed.
+ * wtf/unicode/qt4/UnicodeQt4.h:
+ * wtf/unicode/wince/UnicodeWince.h:
+
+2010-09-13 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Preparation for eliminating deprecatedParseURL
+ https://bugs.webkit.org/show_bug.cgi?id=45695
+
+ * wtf/text/WTFString.h: Added isAllSpecialCharacters, moved here from
+ the HTML tree builder.
+
+2010-09-13 Darin Fisher <darin@chromium.org>
+
+ Reviewed by David Levin.
+
+ Add option to conditionally compile smooth scrolling support.
+ https://bugs.webkit.org/show_bug.cgi?id=45689
+
+ ENABLE(SMOOTH_SCROLLING) is disabled by default for all platforms.
+
+ * wtf/Platform.h:
+
+2010-09-13 Adam Roben <aroben@apple.com>
+
+ Copy JavaScriptCore's generated sources to the right directory
+
+ * JavaScriptCore.vcproj/JavaScriptCore.make: Fixed typo.
+
+2010-09-13 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Don't call _msize
+ https://bugs.webkit.org/show_bug.cgi?id=45556
+
+ Because Brew MP uses its own memory allocator, it is not correct to use
+ _msize in fastMallocSize. Add !PLATFORM(BREWMP) guard.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMallocSize):
+
+2010-09-11 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] V8 port: webcore project files changes
+ https://bugs.webkit.org/show_bug.cgi?id=45141
+
+ * JavaScriptCore.pro: Moved wtf specific files to wtf.pri,
+ so that they can also be used from WebCore.pro for v8 builds.
+ * wtf/wtf.pri: Added.
+
+2010-09-10 Fridrich Strba <fridrich.strba@bluewin.ch>
+
+ Reviewed by Andreas Kling.
+
+ Add a define missing when building with glib unicode backend
+ https://bugs.webkit.org/show_bug.cgi?id=45544
+
+ * wtf/unicode/glib/UnicodeMacrosFromICU.h:
+
+2010-09-10 Stephanie Lewis <slewis@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Refactor JavaScriptCore memory statistics so that WebKit doesn't need to know
+ about the JIT and other implementation details of JavaScriptCore. Necessary
+ to fix PPC build.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45528
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/MemoryStatistics.cpp: Added.
+ (JSC::memoryStatistics):
+ * runtime/MemoryStatistics.h: Added.
+
2010-09-09 Michael Saboff <msaboff@apple.com>
Reviewed by Gavin Barraclough.
diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index f2b4c09..2ed3a8e 100644
--- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -69,7 +69,6 @@ ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE;
ENABLE_FILTERS = $(ENABLE_FILTERS_$(REAL_PLATFORM_NAME));
ENABLE_FILTERS_macosx = ENABLE_FILTERS;
-ENABLE_FILE_WRITER = ;
ENABLE_FILE_SYSTEM = ;
ENABLE_GEOLOCATION = ENABLE_GEOLOCATION;
@@ -120,4 +119,4 @@ ENABLE_XHTMLMP = ;
ENABLE_XPATH = ENABLE_XPATH;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_WRITER) $(ENABLE_FILE_SYSTEM) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_SYSTEM) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 673e234..e82e464 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 8;
+MINOR_VERSION = 9;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index ee0bfb7..13b9676 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -132,7 +132,6 @@ __ZN3JSC12JSGlobalData14sharedInstanceEv
__ZN3JSC12JSGlobalData15dumpRegExpTraceEv
__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
__ZN3JSC12JSGlobalDataD1Ev
-__ZN3JSC12RegisterFile18committedByteCountEv
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
@@ -151,6 +150,7 @@ __ZN3JSC13SamplingFlags4stopEv
__ZN3JSC13SamplingFlags5startEv
__ZN3JSC13SamplingFlags7s_flagsE
__ZN3JSC13StatementNode6setLocEii
+__ZN3JSC14heapStatisticsEPNS_12JSGlobalDataE
__ZN3JSC14JSGlobalObject10globalExecEv
__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
@@ -168,7 +168,6 @@ __ZN3JSC14TimeoutChecker5resetEv
__ZN3JSC14throwTypeErrorEPNS_9ExecStateE
__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC15toInt32SlowCaseEdRb
__ZN3JSC16InternalFunction4infoE
__ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_10IdentifierE
@@ -178,7 +177,6 @@ __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNam
__ZN3JSC16WeakGCHandlePool4freeEPNS_12WeakGCHandleE
__ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE
-__ZN3JSC16toUInt32SlowCaseEdRb
__ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
@@ -193,10 +191,10 @@ __ZN3JSC18PropertyDescriptor17defaultAttributesE
__ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j
__ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE
__ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE
-__ZN3JSC19ExecutableAllocator18committedByteCountEv
__ZN3JSC19initializeThreadingEv
__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC22globalMemoryStatisticsEv
__ZN3JSC23AbstractSamplingCounter4dumpEv
__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
@@ -241,7 +239,6 @@ __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
__ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
__ZN3JSC6JSLock9lockCountEv
__ZN3JSC6JSLockC1EPNS_9ExecStateE
-__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
__ZN3JSC7JSArray15setSubclassDataEPv
__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
@@ -264,6 +261,7 @@ __ZN3JSC7UStringC1EPKc
__ZN3JSC7UStringC1EPKcj
__ZN3JSC7UStringC1EPKt
__ZN3JSC7UStringC1EPKtj
+__ZN3JSC7toInt32Ed
__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro
index 7f6b27d..f463f41 100644
--- a/JavaScriptCore/JavaScriptCore.pro
+++ b/JavaScriptCore/JavaScriptCore.pro
@@ -66,6 +66,7 @@ wince* {
}
include(pcre/pcre.pri)
+include(wtf/wtf.pri)
SOURCES += \
API/JSBase.cpp \
@@ -203,42 +204,11 @@ SOURCES += \
runtime/Structure.cpp \
runtime/TimeoutChecker.cpp \
runtime/UString.cpp \
- wtf/Assertions.cpp \
- wtf/ByteArray.cpp \
- wtf/CurrentTime.cpp \
- wtf/DateMath.cpp \
- wtf/dtoa.cpp \
- wtf/FastMalloc.cpp \
- wtf/HashTable.cpp \
- wtf/MD5.cpp \
- wtf/MainThread.cpp \
- wtf/qt/MainThreadQt.cpp \
- wtf/qt/StringQt.cpp \
- wtf/qt/ThreadingQt.cpp \
- wtf/PageAllocation.cpp \
- wtf/RandomNumber.cpp \
- wtf/RefCountedLeakCounter.cpp \
- wtf/ThreadingNone.cpp \
- wtf/Threading.cpp \
- wtf/TypeTraits.cpp \
- wtf/WTFThreadData.cpp \
- wtf/text/AtomicString.cpp \
- wtf/text/CString.cpp \
- wtf/text/StringImpl.cpp \
- wtf/text/StringStatics.cpp \
- wtf/text/WTFString.cpp \
- wtf/unicode/CollatorDefault.cpp \
- wtf/unicode/icu/CollatorICU.cpp \
- wtf/unicode/UTF8.cpp \
yarr/RegexCompiler.cpp \
yarr/RegexInterpreter.cpp \
yarr/RegexJIT.cpp
# Generated files, simply list them for JavaScriptCore
-!contains(DEFINES, USE_SYSTEM_MALLOC) {
- SOURCES += wtf/TCSystemAlloc.cpp
-}
-
# Disable C++0x mode in JSC for those who enabled it in their Qt's mkspec
*-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
index 4c47ac6..4f049c9 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
@@ -32,4 +32,4 @@ install:
xcopy "$(OBJROOT)\lib\*" "$(DSTROOT)\AppleInternal\lib\" /e/v/i/h/y
xcopy "$(OBJROOT)\bin\JavaScriptCore.resources\*" "$(DSTROOT)\AppleInternal\bin\JavaScriptCore.resources" /e/v/i/h/y
-mkdir "$(DSTROOT)\AppleInternal\Sources\JavaScriptCore"
- xcopy "$(OBJROOT)\obj\JavaScriptCore\DerivedSources\*" "$(DSTROOT)\AppleInternal\Sources\WebCore" /e/v/i/h/y
+ xcopy "$(OBJROOT)\obj\JavaScriptCore\DerivedSources\*" "$(DSTROOT)\AppleInternal\Sources\JavaScriptCore" /e/v/i/h/y
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 7226326..ba564f0 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -232,7 +232,6 @@ EXPORTS
?nonInlineNaN@JSC@@YANXZ
?objectCount@Heap@JSC@@QBEIXZ
?objectProtoFuncToString@JSC@@YI_JPAVExecState@1@@Z
- ?parse@Parser@JSC@@AAEXPAVJSGlobalData@2@PAHPAVUString@2@@Z
?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z
?pool@WeakGCHandle@JSC@@QAEPAVWeakGCHandlePool@2@XZ
?profiler@Profiler@JSC@@SAPAV12@XZ
@@ -305,7 +304,7 @@ EXPORTS
?toBoolean@JSCell@JSC@@UBE_NPAVExecState@2@@Z
?toBoolean@JSObject@JSC@@UBE_NPAVExecState@2@@Z
?toBoolean@JSString@JSC@@EBE_NPAVExecState@2@@Z
- ?toInt32SlowCase@JSC@@YAHNAA_N@Z
+ ?toInt32@JSC@@YAHN@Z
?toInteger@JSValue@JSC@@QBENPAVExecState@2@@Z
?toNumber@JSCell@JSC@@UBENPAVExecState@2@@Z
?toNumber@JSObject@JSC@@UBENPAVExecState@2@@Z
@@ -324,7 +323,6 @@ EXPORTS
?toThisObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z
?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
?toUInt32@Identifier@JSC@@SAIABVUString@2@AA_N@Z
- ?toUInt32SlowCase@JSC@@YAINAA_N@Z
?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z
?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z
?tryLock@Mutex@WTF@@QAE_NXZ
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
index a9493a3..098ff08 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
@@ -1,5 +1,4 @@
all:
- -if not exist "$(WEBKITLIBRARIESDIR)\tools\vsprops\.svn" del /s/q "$(WEBKITLIBRARIESDIR)\tools\vsprops\"
-xcopy /y/d/e/i "..\..\..\WebKitLibraries\win\tools" "$(WEBKITLIBRARIESDIR)\tools"
touch "$(WEBKITOUTPUTDIR)\buildfailed"
bash build-generated-files.sh "$(WEBKITOUTPUTDIR)" "$(WEBKITLIBRARIESDIR)"
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index bee44b6..675d26d 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -258,6 +258,8 @@
86EAC49B0F93E8D1008EC948 /* RegexParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC4930F93E8D1008EC948 /* RegexParser.h */; };
86EAC49C0F93E8D1008EC948 /* RegexPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC4940F93E8D1008EC948 /* RegexPattern.h */; };
86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F38858121130CA007A7CE3 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */; };
+ 90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */; };
90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93052C320FB792190048FDC3 /* ParserArena.cpp */; };
@@ -859,6 +861,8 @@
86EAC4930F93E8D1008EC948 /* RegexParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexParser.h; path = yarr/RegexParser.h; sourceTree = "<group>"; };
86EAC4940F93E8D1008EC948 /* RegexPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexPattern.h; path = yarr/RegexPattern.h; sourceTree = "<group>"; };
86F38858121130CA007A7CE3 /* AtomicStringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringHash.h; path = text/AtomicStringHash.h; sourceTree = "<group>"; };
+ 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStatistics.cpp; sourceTree = "<group>"; };
+ 90213E3C123A40C200D422F3 /* MemoryStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryStatistics.h; sourceTree = "<group>"; };
905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCountedLeakCounter.cpp; sourceTree = "<group>"; };
90D3469B0E285280009492EE /* RefCountedLeakCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCountedLeakCounter.h; sourceTree = "<group>"; };
9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; };
@@ -1735,6 +1739,8 @@
A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */,
F692A86A0255597D01FF60F7 /* MathObject.cpp */,
F692A86B0255597D01FF60F7 /* MathObject.h */,
+ 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */,
+ 90213E3C123A40C200D422F3 /* MemoryStatistics.h */,
BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */,
BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */,
BC02E90A0E1839DB000F9297 /* NativeErrorPrototype.cpp */,
@@ -2307,6 +2313,7 @@
9714AF4F122F289A0092D9F5 /* URLSegments.h in Headers */,
9714AF5F122F32070092D9F5 /* ParsedURL.h in Headers */,
9714AF60122F32070092D9F5 /* URLString.h in Headers */,
+ 90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2760,6 +2767,7 @@
A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */,
9714AF46122F28850092D9F5 /* URLSegments.cpp in Sources */,
9714AF5E122F32070092D9F5 /* ParsedURL.cpp in Sources */,
+ 90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/parser/ASTBuilder.h b/JavaScriptCore/parser/ASTBuilder.h
index dbf3c07..40023f8 100644
--- a/JavaScriptCore/parser/ASTBuilder.h
+++ b/JavaScriptCore/parser/ASTBuilder.h
@@ -100,6 +100,7 @@ public:
typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
static const bool CreatesAST = true;
+ static const bool NeedsFreeVariableInfo = true;
ExpressionNode* makeBinaryNode(int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
ExpressionNode* makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp
index 820811e..540dc3b 100644
--- a/JavaScriptCore/parser/JSParser.cpp
+++ b/JavaScriptCore/parser/JSParser.cpp
@@ -67,7 +67,7 @@ static const ptrdiff_t kMaxParserStackUsage = 128 * sizeof(void*) * 1024;
class JSParser {
public:
- JSParser(Lexer*, JSGlobalData*, SourceProvider*);
+ JSParser(Lexer*, JSGlobalData*, FunctionParameters*, SourceProvider*);
bool parseProgram();
private:
struct AllowInOverride {
@@ -161,7 +161,7 @@ private:
template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd);
template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context);
enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
- template <FunctionRequirements, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine);
+ template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine);
ALWAYS_INLINE int isBinaryOperator(JSTokenType token);
bool allowAutomaticSemicolon();
@@ -199,15 +199,105 @@ private:
int m_assignmentCount;
int m_nonLHSCount;
bool m_syntaxAlreadyValidated;
+
+ struct Scope {
+ Scope()
+ : m_usesEval(false)
+ , m_needsFullActivation(false)
+ {
+ }
+
+ void declareVariable(const Identifier* ident)
+ {
+ m_declaredVariables.add(ident->ustring().impl());
+ }
+
+ void useVariable(const Identifier* ident, bool isEval)
+ {
+ m_usesEval |= isEval;
+ m_usedVariables.add(ident->ustring().impl());
+ }
+
+ void needsFullActivation() { m_needsFullActivation = true; }
+
+ void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
+ {
+ if (nestedScope->m_usesEval)
+ m_usesEval = true;
+ IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
+ for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
+ if (nestedScope->m_declaredVariables.contains(*ptr))
+ continue;
+ m_usedVariables.add(*ptr);
+ if (shouldTrackClosedVariables)
+ m_closedVariables.add(*ptr);
+ }
+ }
+
+ void getCapturedVariables(IdentifierSet& capturedVariables)
+ {
+ if (m_needsFullActivation || m_usesEval) {
+ capturedVariables.swap(m_declaredVariables);
+ return;
+ }
+ for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
+ if (!m_declaredVariables.contains(*ptr))
+ continue;
+ capturedVariables.add(*ptr);
+ }
+ }
+ private:
+ bool m_usesEval;
+ bool m_needsFullActivation;
+ IdentifierSet m_declaredVariables;
+ IdentifierSet m_usedVariables;
+ IdentifierSet m_closedVariables;
+ };
+
+ typedef Vector<Scope, 10> ScopeStack;
+
+ struct ScopeRef {
+ ScopeRef(ScopeStack* scopeStack, unsigned index)
+ : m_scopeStack(scopeStack)
+ , m_index(index)
+ {
+ }
+ Scope* operator->() { return &m_scopeStack->at(m_index); }
+ unsigned index() const { return m_index; }
+ private:
+ ScopeStack* m_scopeStack;
+ unsigned m_index;
+ };
+
+ ScopeRef currentScope()
+ {
+ return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
+ }
+
+ ScopeRef pushScope()
+ {
+ m_scopeStack.append(Scope());
+ return currentScope();
+ }
+
+ void popScope(ScopeRef scope, bool shouldTrackClosedVariables)
+ {
+ ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
+ ASSERT(m_scopeStack.size() > 1);
+ m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
+ m_scopeStack.removeLast();
+ }
+
+ ScopeStack m_scopeStack;
};
-int jsParse(JSGlobalData* globalData, const SourceCode* source)
+int jsParse(JSGlobalData* globalData, FunctionParameters* parameters, const SourceCode* source)
{
- JSParser parser(globalData->lexer, globalData, source->provider());
+ JSParser parser(globalData->lexer, globalData, parameters, source->provider());
return parser.parseProgram();
}
-JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, SourceProvider* provider)
+JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, SourceProvider* provider)
: m_lexer(lexer)
, m_endAddress(0)
, m_error(false)
@@ -223,16 +313,24 @@ JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, SourceProvider* provi
m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage;
next();
m_lexer->setLastLineNumber(tokenLine());
+ ScopeRef scope = pushScope();
+ if (parameters) {
+ for (unsigned i = 0; i < parameters->size(); i++)
+ scope->declareVariable(&parameters->at(i));
+ }
}
bool JSParser::parseProgram()
{
ASTBuilder context(m_globalData, m_lexer);
+ ScopeRef scope = currentScope();
SourceElements* sourceElements = parseSourceElements<ASTBuilder>(context);
if (!sourceElements || !consume(EOFTOK))
return true;
+ IdentifierSet capturedVariables;
+ scope->getCapturedVariables(capturedVariables);
m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features(),
- m_lastLine, context.numConstants());
+ m_lastLine, context.numConstants(), capturedVariables);
return false;
}
@@ -327,6 +425,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr
lastIdent = name;
next();
bool hasInitializer = match(EQUAL);
+ currentScope()->declareVariable(name);
context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
if (hasInitializer) {
int varDivot = tokenStart() + 1;
@@ -358,6 +457,7 @@ template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationLi
const Identifier* name = m_token.m_data.ident;
next();
bool hasInitializer = match(EQUAL);
+ currentScope()->declareVariable(name);
context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
TreeExpression initializer = 0;
if (hasInitializer) {
@@ -552,6 +652,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseThrowStatement(TreeBui
template <class TreeBuilder> TreeStatement JSParser::parseWithStatement(TreeBuilder& context)
{
ASSERT(match(WITH));
+ currentScope()->needsFullActivation();
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -650,17 +751,21 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild
int lastLine = m_lastLine;
if (match(CATCH)) {
+ currentScope()->needsFullActivation();
next();
consumeOrFail(OPENPAREN);
matchOrFail(IDENT);
ident = m_token.m_data.ident;
next();
+ ScopeRef catchScope = pushScope();
+ catchScope->declareVariable(ident);
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
int initialEvalCount = context.evalCount();
catchBlock = parseBlockStatement(context);
failIfFalse(catchBlock);
catchHasEval = initialEvalCount != context.evalCount();
+ popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
}
if (match(FINALLY)) {
@@ -757,6 +862,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
{
matchOrFail(IDENT);
usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident;
+ currentScope()->declareVariable(m_token.m_data.ident);
TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
TreeFormalParameterList tail = list;
next();
@@ -764,6 +870,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
next();
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
+ currentScope()->declareVariable(ident);
next();
usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident;
tail = context.createFormalParameterList(tail, *ident);
@@ -780,11 +887,14 @@ template <class TreeBuilder> TreeFunctionBody JSParser::parseFunctionBody(TreeBu
return context.createFunctionBody();
}
-template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
+template <JSParser::FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
{
+ ScopeRef functionScope = pushScope();
if (match(IDENT)) {
name = m_token.m_data.ident;
next();
+ if (!nameIsInContainingScope)
+ functionScope->declareVariable(name);
} else if (requirements == FunctionNeedsName)
return false;
consumeOrFail(OPENPAREN);
@@ -804,7 +914,7 @@ template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool J
failIfFalse(body);
if (usesArguments)
context.setUsesArguments(body);
-
+ popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
matchOrFail(CLOSEBRACE);
closeBracePos = m_token.m_data.intValue;
next();
@@ -821,8 +931,9 @@ template <class TreeBuilder> TreeStatement JSParser::parseFunctionDeclaration(Tr
int openBracePos = 0;
int closeBracePos = 0;
int bodyStartLine = 0;
- failIfFalse(parseFunctionInfo<FunctionNeedsName>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine));
+ failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
failIfFalse(name);
+ currentScope()->declareVariable(name);
return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
@@ -1113,7 +1224,7 @@ template <bool complete, class TreeBuilder> TreeProperty JSParser::parseProperty
type = PropertyNode::Setter;
else
fail();
- failIfFalse(parseFunctionInfo<FunctionNeedsName>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine));
+ failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
return context.template createGetterOrSetterProperty<complete>(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
case NUMBER: {
@@ -1281,6 +1392,7 @@ template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(Tre
int start = tokenStart();
const Identifier* ident = m_token.m_data.ident;
next();
+ currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
return context.createResolve(ident, start);
}
case STRING: {
@@ -1364,7 +1476,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
int closeBracePos = 0;
int bodyStartLine = 0;
next();
- failIfFalse(parseFunctionInfo<FunctionNoRequirements>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine));
+ failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
base = context.createFunctionExpr(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
} else
base = parsePrimaryExpression(context);
diff --git a/JavaScriptCore/parser/JSParser.h b/JavaScriptCore/parser/JSParser.h
index b5a21d9..ab18fab 100644
--- a/JavaScriptCore/parser/JSParser.h
+++ b/JavaScriptCore/parser/JSParser.h
@@ -28,6 +28,7 @@
namespace JSC {
+class FunctionParameters;
class Identifier;
class JSGlobalData;
class SourceCode;
@@ -154,6 +155,6 @@ struct JSToken {
JSTokenInfo m_info;
};
-int jsParse(JSGlobalData*, const SourceCode*);
+int jsParse(JSGlobalData*, FunctionParameters*, const SourceCode*);
}
#endif // JSParser_h
diff --git a/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp
index c41d735..534e28a 100644
--- a/JavaScriptCore/parser/Nodes.cpp
+++ b/JavaScriptCore/parser/Nodes.cpp
@@ -75,7 +75,7 @@ StatementNode* SourceElements::singleStatement() const
// -----------------------------ScopeNodeData ---------------------------
-ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants)
+ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
: m_numConstants(numConstants)
, m_statements(statements)
{
@@ -84,6 +84,7 @@ ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, Var
m_varStack.swap(*varStack);
if (funcStack)
m_functionStack.swap(*funcStack);
+ m_capturedVariables.swap(capturedVariables);
}
// ------------------------------ ScopeNode -----------------------------
@@ -95,10 +96,10 @@ ScopeNode::ScopeNode(JSGlobalData* globalData)
{
}
-ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
+ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
: StatementNode(globalData)
, ParserArenaRefCounted(globalData)
- , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, numConstants)))
+ , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, numConstants)))
, m_features(features)
, m_source(source)
{
@@ -111,14 +112,14 @@ StatementNode* ScopeNode::singleStatement() const
// ------------------------------ ProgramNode -----------------------------
-inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
+inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
+ RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->data()->m_arena.last() == node);
node->data()->m_arena.removeLast();
@@ -129,14 +130,14 @@ PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElem
// ------------------------------ EvalNode -----------------------------
-inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
+inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
+ RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->data()->m_arena.last() == node);
node->data()->m_arena.removeLast();
@@ -158,8 +159,8 @@ inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
{
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
@@ -181,9 +182,9 @@ FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
return new FunctionBodyNode(globalData);
}
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
{
- RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
ASSERT(node->data()->m_arena.last() == node);
node->data()->m_arena.removeLast();
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index d25079b..2d8448c 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -81,6 +81,8 @@ namespace JSC {
OpLogicalOr
};
+ typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
+
namespace DeclarationStacks {
enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
@@ -1376,13 +1378,14 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
+ ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
ParserArena m_arena;
VarStack m_varStack;
FunctionStack m_functionStack;
int m_numConstants;
SourceElements* m_statements;
+ IdentifierSet m_capturedVariables;
};
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
@@ -1391,7 +1394,7 @@ namespace JSC {
typedef DeclarationStacks::FunctionStack FunctionStack;
ScopeNode(JSGlobalData*);
- ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);
+ ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
@@ -1409,7 +1412,8 @@ namespace JSC {
bool usesArguments() const { return m_features & ArgumentsFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+ bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
@@ -1437,24 +1441,24 @@ namespace JSC {
class ProgramNode : public ScopeNode {
public:
- static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
class EvalNode : public ScopeNode {
public:
- static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1470,7 +1474,7 @@ namespace JSC {
class FunctionBodyNode : public ScopeNode {
public:
static FunctionBodyNode* create(JSGlobalData*);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
@@ -1486,7 +1490,7 @@ namespace JSC {
private:
FunctionBodyNode(JSGlobalData*);
- FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
RefPtr<FunctionParameters> m_parameters;
diff --git a/JavaScriptCore/parser/Parser.cpp b/JavaScriptCore/parser/Parser.cpp
index 39ff597..bd77742 100644
--- a/JavaScriptCore/parser/Parser.cpp
+++ b/JavaScriptCore/parser/Parser.cpp
@@ -39,7 +39,7 @@ extern int jscyyparse(void*);
namespace JSC {
-void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
+void Parser::parse(JSGlobalData* globalData, FunctionParameters* parameters, int* errLine, UString* errMsg)
{
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::JavaScriptParseTimeCounter);
@@ -60,7 +60,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
Lexer& lexer = *globalData->lexer;
lexer.setCode(*m_source, m_arena);
- int parseError = jsParse(globalData, m_source);
+ int parseError = jsParse(globalData, parameters, m_source);
int lineNumber = lexer.lineNumber();
bool lexError = lexer.sawError();
lexer.clear();
@@ -76,11 +76,12 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
}
void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
- ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
+ ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
{
m_sourceElements = sourceElements;
m_varDeclarations = varStack;
m_funcDeclarations = funcStack;
+ m_capturedVariables.swap(capturedVars);
m_features = features;
m_lastLine = lastLine;
m_numConstants = numConstants;
diff --git a/JavaScriptCore/parser/Parser.h b/JavaScriptCore/parser/Parser.h
index c167980..9134de1 100644
--- a/JavaScriptCore/parser/Parser.h
+++ b/JavaScriptCore/parser/Parser.h
@@ -48,15 +48,16 @@ namespace JSC {
class Parser : public Noncopyable {
public:
template <class ParsedNode>
- PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, JSObject** exception);
+ PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSObject** exception);
void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
- ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
+ ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features,
+ int lastLine, int numConstants, IdentifierSet&);
ParserArena& arena() { return m_arena; }
private:
- void parse(JSGlobalData*, int* errLine, UString* errMsg);
+ void parse(JSGlobalData*, FunctionParameters*, int* errLine, UString* errMsg);
// Used to determine type of error to report.
bool isFunctionBodyNode(ScopeNode*) { return false; }
@@ -67,13 +68,14 @@ namespace JSC {
SourceElements* m_sourceElements;
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
+ IdentifierSet m_capturedVariables;
CodeFeatures m_features;
int m_lastLine;
int m_numConstants;
};
template <class ParsedNode>
- PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, JSObject** exception)
+ PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSObject** exception)
{
ASSERT(exception && !*exception);
int errLine;
@@ -82,17 +84,18 @@ namespace JSC {
m_source = &source;
if (ParsedNode::scopeIsFunction)
globalData->lexer->setIsReparsing();
- parse(globalData, &errLine, &errMsg);
+ parse(globalData, parameters, &errLine, &errMsg);
RefPtr<ParsedNode> result;
if (m_sourceElements) {
result = ParsedNode::create(globalData,
- m_sourceElements,
- m_varDeclarations ? &m_varDeclarations->data : 0,
- m_funcDeclarations ? &m_funcDeclarations->data : 0,
- source,
- m_features,
- m_numConstants);
+ m_sourceElements,
+ m_varDeclarations ? &m_varDeclarations->data : 0,
+ m_funcDeclarations ? &m_funcDeclarations->data : 0,
+ m_capturedVariables,
+ source,
+ m_features,
+ m_numConstants);
result->setLoc(m_source->firstLine(), m_lastLine);
} else if (lexicalGlobalObject) {
// We can never see a syntax error when reparsing a function, since we should have
diff --git a/JavaScriptCore/parser/SyntaxChecker.h b/JavaScriptCore/parser/SyntaxChecker.h
index e05facd..ce3ab61 100644
--- a/JavaScriptCore/parser/SyntaxChecker.h
+++ b/JavaScriptCore/parser/SyntaxChecker.h
@@ -70,6 +70,7 @@ public:
typedef int BinaryOperand;
static const bool CreatesAST = false;
+ static const bool NeedsFreeVariableInfo = false;
int createSourceElements() { return 1; }
int makeFunctionCallNode(int, int, int, int, int) { return 1; }
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 4a81913..93b91bb 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -43,6 +43,7 @@
#include <stdlib.h>
#include <wtf/FastMalloc.h>
#include <wtf/HashCountedSet.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
@@ -298,6 +299,7 @@ void Heap::recordExtraCost(size_t cost)
void* Heap::allocate(size_t s)
{
+ ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
typedef HeapConstants::Block Block;
typedef HeapConstants::Cell Cell;
@@ -1189,6 +1191,7 @@ bool Heap::isBusy()
void Heap::reset()
{
+ ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
JAVASCRIPTCORE_GC_BEGIN();
markRoots();
@@ -1211,6 +1214,7 @@ void Heap::reset()
void Heap::collectAllGarbage()
{
+ ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
JAVASCRIPTCORE_GC_BEGIN();
// If the last iteration through the heap deallocated blocks, we need
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index 249f427..4983f29 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -301,19 +301,25 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
// hours
if (maxArgs >= 4 && idx < numArgs) {
t->hour = 0;
- milliseconds += exec->argument(idx++).toInt32(exec, ok) * msPerHour;
+ double hours = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(hours);
+ milliseconds += hours * msPerHour;
}
// minutes
if (maxArgs >= 3 && idx < numArgs && ok) {
t->minute = 0;
- milliseconds += exec->argument(idx++).toInt32(exec, ok) * msPerMinute;
+ double minutes = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(minutes);
+ milliseconds += minutes * msPerMinute;
}
// seconds
if (maxArgs >= 2 && idx < numArgs && ok) {
t->second = 0;
- milliseconds += exec->argument(idx++).toInt32(exec, ok) * msPerSecond;
+ double seconds = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(seconds);
+ milliseconds += seconds * msPerSecond;
}
if (!ok)
@@ -321,7 +327,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
// milliseconds
if (idx < numArgs) {
- double millis = exec->argument(idx).toNumber(exec);
+ double millis = exec->argument(idx).toIntegerPreserveNaN(exec);
ok = isfinite(millis);
milliseconds += millis;
} else
@@ -346,17 +352,23 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, int maxArgs, double *ms
numArgs = maxArgs;
// years
- if (maxArgs >= 3 && idx < numArgs)
- t->year = exec->argument(idx++).toInt32(exec, ok) - 1900;
-
+ if (maxArgs >= 3 && idx < numArgs) {
+ double years = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(years);
+ t->year = toInt32(years - 1900);
+ }
// months
- if (maxArgs >= 2 && idx < numArgs && ok)
- t->month = exec->argument(idx++).toInt32(exec, ok);
-
+ if (maxArgs >= 2 && idx < numArgs && ok) {
+ double months = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(months);
+ t->month = toInt32(months);
+ }
// days
- if (idx < numArgs && ok) {
+ if (idx < numArgs && ok) {
+ double days = exec->argument(idx++).toIntegerPreserveNaN(exec);
+ ok = isfinite(days);
t->monthDay = 0;
- *ms += exec->argument(idx).toInt32(exec, ok) * msPerDay;
+ *ms += days * msPerDay;
}
return ok;
@@ -1026,15 +1038,14 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
gregorianDateTime.copyFrom(*other);
}
- bool ok = true;
- int32_t year = exec->argument(0).toInt32(exec, ok);
- if (!ok) {
+ double year = exec->argument(0).toIntegerPreserveNaN(exec);
+ if (!isfinite(year)) {
JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return JSValue::encode(result);
}
- gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year;
+ gregorianDateTime.year = toInt32((year > 99 || year < 0) ? year - 1900 : year);
JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
thisDateObj->setInternalValue(result);
return JSValue::encode(result);
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 41b5f1f..e14955c 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -96,12 +96,12 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
if (!evalNode) {
ASSERT(exception);
return exception;
}
- recordParse(evalNode->features(), evalNode->lineNo(), evalNode->lastLine());
+ recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
@@ -131,7 +131,7 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
if (programNode)
return 0;
ASSERT(exception);
@@ -145,12 +145,12 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
if (!programNode) {
ASSERT(exception);
return exception;
}
- recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine());
+ recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
@@ -178,7 +178,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -186,7 +186,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
if (m_forceUsesArguments)
body->setUsesArguments();
body->finishParsing(m_parameters, m_name);
- recordParse(body->features(), body->lineNo(), body->lastLine());
+ recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
@@ -219,7 +219,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -227,7 +227,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
if (m_forceUsesArguments)
body->setUsesArguments();
body->finishParsing(m_parameters, m_name);
- recordParse(body->features(), body->lineNo(), body->lastLine());
+ recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
@@ -267,7 +267,7 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, &exception);
+ RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, m_parameters.get(), &exception);
if (!newFunctionBody)
return PassOwnPtr<ExceptionInfo>();
if (m_forceUsesArguments)
@@ -301,7 +301,7 @@ PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData*
PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, &exception);
+ RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, 0, &exception);
if (!newEvalBody)
return PassOwnPtr<ExceptionInfo>();
@@ -341,7 +341,7 @@ void FunctionExecutable::recompile(ExecState*)
PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, debugger, exec, source, exception);
+ RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, debugger, exec, source, 0, exception);
if (!program) {
ASSERT(*exception);
return 0;
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index 10dfb34..c168ac8 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -172,20 +172,22 @@ namespace JSC {
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
- bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
protected:
- void recordParse(CodeFeatures features, int firstLine, int lastLine)
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
{
m_features = features;
+ m_hasCapturedVariables = hasCapturedVariables;
m_firstLine = firstLine;
m_lastLine = lastLine;
}
SourceCode m_source;
CodeFeatures m_features;
+ bool m_hasCapturedVariables;
int m_firstLine;
int m_lastLine;
};
diff --git a/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
index 06d4210..45329ca 100644
--- a/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
+++ b/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
@@ -29,9 +29,12 @@
#include "config.h"
#include "GCActivityCallback.h"
+#include "APIShims.h"
#include "Collector.h"
+#include "JSGlobalData.h"
#include "JSLock.h"
#include <wtf/RetainPtr.h>
+#include <wtf/WTFThreadData.h>
#include <CoreFoundation/CoreFoundation.h>
#if !PLATFORM(CF)
@@ -52,8 +55,7 @@ const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10;
void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef, void *info)
{
Heap* heap = static_cast<Heap*>(info);
- JSLock lock(heap->globalData());
-
+ APIEntryShim shim(heap->globalData());
heap->collectAllGarbage();
}
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 55aa327..340cb75 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -1060,10 +1060,11 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
if (storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
return;
- if (!storage->m_length)
- return;
-
unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
+ unsigned nodeCount = usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0);
+
+ if (!nodeCount)
+ return;
AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
tree.abstractor().m_exec = exec;
@@ -1071,7 +1072,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
tree.abstractor().m_compareCallType = callType;
tree.abstractor().m_compareCallData = &callData;
tree.abstractor().m_globalThisValue = exec->globalThisValue();
- tree.abstractor().m_nodes.resize(usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0));
+ tree.abstractor().m_nodes.grow(nodeCount);
if (callType == CallTypeJS)
tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, asFunction(compareFunction), 2, exec->exceptionSlot()));
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp
index 6db6954..2a23a79 100644
--- a/JavaScriptCore/runtime/JSValue.cpp
+++ b/JavaScriptCore/runtime/JSValue.cpp
@@ -135,36 +135,49 @@ char* JSValue::description()
}
#endif
-int32_t toInt32SlowCase(double d, bool& ok)
+// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
+// Note that this operation is identical to ToUInt32 other than to interpretation
+// of the resulting bit-pattern (as such this metod is also called to implement
+// ToUInt32).
+//
+// The operation can be descibed as round towards zero, then select the 32 least
+// bits of the resulting value in 2s-complement representation.
+int32_t toInt32(double number)
{
- if (isnan(d) || isinf(d)) {
- ok = false;
+ int64_t bits = WTF::bitwise_cast<int64_t>(number);
+ int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff;
+
+ // If exponent < 0 there will be no bits to the left of the decimal point
+ // after rounding; if the exponent is > 83 then no bits of precision can be
+ // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits
+ // of fractional precision).
+ // Note this case handles 0, -0, and all infinte, NaN, & denormal value.
+ if (exp < 0 || exp > 83)
return 0;
- }
-
- ok = true;
-
- double d32 = fmod(trunc(d), D32);
- if (d32 >= D32 / 2)
- d32 -= D32;
- else if (d32 < -D32 / 2)
- d32 += D32;
- return static_cast<int32_t>(d32);
-}
-uint32_t toUInt32SlowCase(double d, bool& ok)
-{
- if (isnan(d) || isinf(d)) {
- ok = false;
- return 0;
+ // Select the appropriate 32-bits from the floating point mantissa. If the
+ // exponent is 52 then the bits we need to select are already aligned to the
+ // lowest bits of the 64-bit integer representation of tghe number, no need
+ // to shift. If the exponent is greater than 52 we need to shift the value
+ // left by (exp - 52), if the value is less than 52 we need to shift right
+ // accordingly.
+ int32_t result = (exp > 52)
+ ? static_cast<int32_t>(bits << (exp - 52))
+ : static_cast<int32_t>(bits >> (52 - exp));
+
+ // IEEE-754 double precision values are stored omitting an implicit 1 before
+ // the decimal point; we need to reinsert this now. We may also the shifted
+ // invalid bits into the result that are not a part of the mantissa (the sign
+ // and exponent bits from the floatingpoint representation); mask these out.
+ if (exp < 32) {
+ int32_t missingOne = 1 << exp;
+ result &= missingOne - 1;
+ result += missingOne;
}
- ok = true;
-
- double d32 = fmod(trunc(d), D32);
- if (d32 < 0)
- d32 += D32;
- return static_cast<uint32_t>(d32);
+ // If the input value was negative (we could test either 'number' or 'bits',
+ // but testing 'bits' is likely faster) invert the result appropriately.
+ return bits < 0 ? -result : result;
}
NEVER_INLINE double nonInlineNaN()
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index 4a6744d..b5834c1 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -56,8 +56,17 @@ namespace JSC {
#endif
double nonInlineNaN();
- int32_t toInt32SlowCase(double, bool& ok);
- uint32_t toUInt32SlowCase(double, bool& ok);
+
+ // This implements ToInt32, defined in ECMA-262 9.5.
+ int32_t toInt32(double);
+
+ // This implements ToUInt32, defined in ECMA-262 9.6.
+ inline uint32_t toUInt32(double number)
+ {
+ // As commented in the spec, the operation of ToInt32 and ToUint32 only differ
+ // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6.
+ return toInt32(number);
+ }
class JSValue {
friend class JSImmediate;
@@ -163,9 +172,7 @@ namespace JSC {
double toInteger(ExecState*) const;
double toIntegerPreserveNaN(ExecState*) const;
int32_t toInt32(ExecState*) const;
- int32_t toInt32(ExecState*, bool& ok) const;
uint32_t toUInt32(ExecState*) const;
- uint32_t toUInt32(ExecState*, bool& ok) const;
#if ENABLE(JSC_ZOMBIES)
bool isZombie() const;
@@ -367,24 +374,6 @@ namespace JSC {
inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
- inline int32_t toInt32(double val)
- {
- if (!(val >= -2147483648.0 && val < 2147483648.0)) {
- bool ignored;
- return toInt32SlowCase(val, ignored);
- }
- return static_cast<int32_t>(val);
- }
-
- inline uint32_t toUInt32(double val)
- {
- if (!(val >= 0.0 && val < 4294967296.0)) {
- bool ignored;
- return toUInt32SlowCase(val, ignored);
- }
- return static_cast<uint32_t>(val);
- }
-
// FIXME: We should deprecate this and just use JSValue::asCell() instead.
JSCell* asCell(JSValue);
@@ -397,62 +386,13 @@ namespace JSC {
{
if (isInt32())
return asInt32();
-
- double val = toNumber(exec);
-
- if (val >= -2147483648.0 && val < 2147483648.0)
- return static_cast<int32_t>(val);
-
- bool ignored;
- return toInt32SlowCase(val, ignored);
+ return JSC::toInt32(toNumber(exec));
}
inline uint32_t JSValue::toUInt32(ExecState* exec) const
{
- if (isUInt32())
- return asUInt32();
-
- double val = toNumber(exec);
-
- if (val >= 0.0 && val < 4294967296.0)
- return static_cast<uint32_t>(val);
-
- bool ignored;
- return toUInt32SlowCase(val, ignored);
- }
-
- inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
- {
- if (isInt32()) {
- ok = true;
- return asInt32();
- }
-
- double val = toNumber(exec);
-
- if (val >= -2147483648.0 && val < 2147483648.0) {
- ok = true;
- return static_cast<int32_t>(val);
- }
-
- return toInt32SlowCase(val, ok);
- }
-
- inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
- {
- if (isUInt32()) {
- ok = true;
- return asInt32();
- }
-
- double val = toNumber(exec);
-
- if (val >= 0.0 && val < 4294967296.0) {
- ok = true;
- return static_cast<uint32_t>(val);
- }
-
- return toUInt32SlowCase(val, ok);
+ // See comment on JSC::toUInt32, above.
+ return toInt32(exec);
}
#if USE(JSVALUE32_64)
diff --git a/JavaScriptCore/runtime/MemoryStatistics.cpp b/JavaScriptCore/runtime/MemoryStatistics.cpp
new file mode 100644
index 0000000..7fafa9c
--- /dev/null
+++ b/JavaScriptCore/runtime/MemoryStatistics.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#include "config.h"
+#include "MemoryStatistics.h"
+
+#include "ExecutableAllocator.h"
+#include "JSGlobalData.h"
+#include "RegisterFile.h"
+
+namespace JSC {
+
+Heap::Statistics heapStatistics(JSGlobalData* commonGlobalData)
+{
+ return commonGlobalData->heap.statistics();
+}
+
+GlobalMemoryStatistics globalMemoryStatistics()
+{
+ GlobalMemoryStatistics stats;
+
+ stats.stackBytes = RegisterFile::committedByteCount();
+#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
+ stats.JITBytes = ExecutableAllocator::committedByteCount();
+#else
+ stats.JITBytes = 0;
+#endif
+ return stats;
+}
+
+}
+
+
diff --git a/JavaScriptCore/runtime/MemoryStatistics.h b/JavaScriptCore/runtime/MemoryStatistics.h
new file mode 100644
index 0000000..1b92eb9
--- /dev/null
+++ b/JavaScriptCore/runtime/MemoryStatistics.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MemoryStatistics_h
+#define MemoryStatistics_h
+
+#include "Collector.h"
+
+class JSGlobalData;
+
+namespace JSC {
+
+struct GlobalMemoryStatistics {
+ size_t stackBytes;
+ size_t JITBytes;
+};
+
+Heap::Statistics heapStatistics(JSGlobalData* commonGlobalData);
+GlobalMemoryStatistics globalMemoryStatistics();
+
+}
+
+#endif // MemoryStatistics_h
+
diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h
index f997374..19de929 100644
--- a/JavaScriptCore/runtime/RegExpObject.h
+++ b/JavaScriptCore/runtime/RegExpObject.h
@@ -45,7 +45,7 @@ namespace JSC {
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual const ClassInfo* classInfo() const { return &info; }
- static const ClassInfo info;
+ static JS_EXPORTDATA const ClassInfo info;
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 0f240ff..1e537b9 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -384,7 +384,8 @@ size_t fastMallocSize(const void* p)
{
#if OS(DARWIN)
return malloc_size(p);
-#elif COMPILER(MSVC)
+#elif COMPILER(MSVC) && !PLATFORM(BREWMP)
+ // Brew MP uses its own memory allocator, so _msize does not work on the Brew MP simulator.
return _msize(const_cast<void*>(p));
#else
return 1;
diff --git a/JavaScriptCore/wtf/OwnPtrCommon.h b/JavaScriptCore/wtf/OwnPtrCommon.h
index 37c135d..19256ea 100644
--- a/JavaScriptCore/wtf/OwnPtrCommon.h
+++ b/JavaScriptCore/wtf/OwnPtrCommon.h
@@ -46,6 +46,8 @@ typedef struct _IFileMgr IFileMgr;
typedef struct _IFile IFile;
typedef struct IBitmap IBitmap;
typedef struct ISSL ISSL;
+typedef struct IMemGroup IMemGroup;
+typedef struct IMemSpace IMemSpace;
#endif
namespace WTF {
@@ -73,6 +75,8 @@ namespace WTF {
void deleteOwnedPtr(IBitmap*);
void deleteOwnedPtr(ISSL*);
void deleteOwnedPtr(ISocket*);
+ void deleteOwnedPtr(IMemGroup*);
+ void deleteOwnedPtr(IMemSpace*);
#endif
} // namespace WTF
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index e77fe98..30bc795 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -1057,6 +1057,10 @@
#define ENABLE_PAN_SCROLLING 1
#endif
+#if !defined(ENABLE_SMOOTH_SCROLLING)
+#define ENABLE_SMOOTH_SCROLLING 0
+#endif
+
/* Use the QXmlStreamReader implementation for XMLDocumentParser */
/* Use the QXmlQuery implementation for XSLTProcessor */
#if PLATFORM(QT)
@@ -1123,7 +1127,7 @@
#define ENABLE_JSC_ZOMBIES 0
/* FIXME: Eventually we should enable this for all platforms and get rid of the define. */
-#if PLATFORM(MAC) || PLATFORM(WIN)
+#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT)
#define WTF_USE_PLATFORM_STRATEGIES 1
#endif
diff --git a/JavaScriptCore/wtf/PlatformRefPtr.h b/JavaScriptCore/wtf/PlatformRefPtr.h
index 2d05ac9..8ac16cb 100644
--- a/JavaScriptCore/wtf/PlatformRefPtr.h
+++ b/JavaScriptCore/wtf/PlatformRefPtr.h
@@ -24,6 +24,7 @@
#define PlatformRefPtr_h
#include "AlwaysInline.h"
+#include "RefPtr.h"
#include <algorithm>
namespace WTF {
@@ -73,6 +74,10 @@ public:
derefPlatformPtr(ptr);
}
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ PlatformRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+
T* get() const { return m_ptr; }
T& operator*() const { return *m_ptr; }
ALWAYS_INLINE T* operator->() const { return m_ptr; }
diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp
index 9e51ad0..a55019b 100644
--- a/JavaScriptCore/wtf/TypeTraits.cpp
+++ b/JavaScriptCore/wtf/TypeTraits.cpp
@@ -47,6 +47,11 @@ COMPILE_ASSERT(!IsInteger<volatile char*>::value, WTF_IsInteger_volatile_char_po
COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false);
COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false);
+COMPILE_ASSERT(IsFloatingPoint<float>::value, WTF_IsFloatingPoint_float_true);
+COMPILE_ASSERT(IsFloatingPoint<double>::value, WTF_IsFloatingPoint_double_true);
+COMPILE_ASSERT(IsFloatingPoint<long double>::value, WTF_IsFloatingPoint_long_double_true);
+COMPILE_ASSERT(!IsFloatingPoint<int>::value, WTF_IsFloatingPoint_int_false);
+
COMPILE_ASSERT(IsPod<bool>::value, WTF_IsPod_bool_true);
COMPILE_ASSERT(IsPod<char>::value, WTF_IsPod_char_true);
COMPILE_ASSERT(IsPod<signed char>::value, WTF_IsPod_signed_char_true);
diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h
index 62dbc49..cf9b4af 100644
--- a/JavaScriptCore/wtf/TypeTraits.h
+++ b/JavaScriptCore/wtf/TypeTraits.h
@@ -62,12 +62,16 @@ namespace WTF {
template<> struct IsInteger<wchar_t> { static const bool value = true; };
#endif
+ template<typename T> struct IsFloatingPoint { static const bool value = false; };
+ template<> struct IsFloatingPoint<float> { static const bool value = true; };
+ template<> struct IsFloatingPoint<double> { static const bool value = true; };
+ template<> struct IsFloatingPoint<long double> { static const bool value = true; };
+
+ template<typename T> struct IsArithmetic { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; };
+
// IsPod is misnamed as it doesn't cover all plain old data (pod) types.
// Specifically, it doesn't allow for enums or for structs.
- template <typename T> struct IsPod { static const bool value = IsInteger<T>::value; };
- template <> struct IsPod<float> { static const bool value = true; };
- template <> struct IsPod<double> { static const bool value = true; };
- template <> struct IsPod<long double> { static const bool value = true; };
+ template <typename T> struct IsPod { static const bool value = IsArithmetic<T>::value; };
template <typename P> struct IsPod<P*> { static const bool value = true; };
template<typename T> class IsConvertibleToInteger {
diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h
index 20ffaca..7f91e1a 100644
--- a/JavaScriptCore/wtf/WTFThreadData.h
+++ b/JavaScriptCore/wtf/WTFThreadData.h
@@ -59,7 +59,14 @@ public:
template<typename U, typename V>
std::pair<HashSet<StringImpl*>::iterator, bool> add(U value);
- void remove(StringImpl* r) { m_table.remove(r); }
+ bool remove(StringImpl* r)
+ {
+ HashSet<StringImpl*>::iterator iter = m_table.find(r);
+ if (iter == m_table.end())
+ return false;
+ m_table.remove(iter);
+ return true;
+ }
LiteralIdentifierTable& literalTable() { return m_literalTable; }
diff --git a/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp b/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp
index 28046bd..ce10fc3 100644
--- a/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp
+++ b/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp
@@ -28,6 +28,8 @@
#include <AEEBitmap.h>
#include <AEEFile.h>
+#include <AEEIMemGroup.h>
+#include <AEEIMemSpace.h>
#include <AEENet.h>
#include <AEESSL.h>
#include <AEEStdLib.h>
@@ -58,6 +60,18 @@ void deleteOwnedPtr(ISSL* ptr)
ISSL_Release(ptr);
}
+void deleteOwnedPtr(IMemGroup* ptr)
+{
+ if (ptr)
+ IMemGroup_Release(ptr);
+}
+
+void deleteOwnedPtr(IMemSpace* ptr)
+{
+ if (ptr)
+ IMemSpace_Release(ptr);
+}
+
void deleteOwnedPtr(ISocket* ptr)
{
if (ptr)
diff --git a/JavaScriptCore/wtf/gobject/GTypedefs.h b/JavaScriptCore/wtf/gobject/GTypedefs.h
index e79ba33..b1600c2 100644
--- a/JavaScriptCore/wtf/gobject/GTypedefs.h
+++ b/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -45,6 +45,7 @@ typedef struct _GdkCursor GdkCursor;
typedef struct _GdkDragContext GdkDragContext;
typedef struct _GdkDrawable GdkDrawable;
typedef struct _GdkEventConfigure GdkEventConfigure;
+typedef struct _GdkEventExpose GdkEventExpose;
typedef struct _GdkPixbuf GdkPixbuf;
typedef struct _GError GError;
typedef struct _GFile GFile;
@@ -79,6 +80,7 @@ typedef struct _GtkStyle GtkStyle;
typedef struct _GtkTargetList GtkTargetList;
typedef struct _GtkThemeParts GtkThemeParts;
typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkWindow GtkWindow;
#ifdef GTK_API_VERSION_2
typedef struct _GdkRectangle GdkRectangle;
diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp
index a667525..7822c00 100644
--- a/JavaScriptCore/wtf/text/StringImpl.cpp
+++ b/JavaScriptCore/wtf/text/StringImpl.cpp
@@ -48,8 +48,10 @@ StringImpl::~StringImpl()
if (isAtomic())
AtomicString::remove(this);
#if USE(JSC)
- if (isIdentifier())
- wtfThreadData().currentIdentifierTable()->remove(this);
+ if (isIdentifier()) {
+ if (!wtfThreadData().currentIdentifierTable()->remove(this))
+ CRASH();
+ }
#endif
BufferOwnership ownership = bufferOwnership();
diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h
index fafef12..8a4a6c7 100644
--- a/JavaScriptCore/wtf/text/WTFString.h
+++ b/JavaScriptCore/wtf/text/WTFString.h
@@ -53,6 +53,7 @@ class BString;
namespace WTF {
class CString;
+struct StringHash;
// Declarations of string operations
@@ -72,6 +73,8 @@ intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trai
double charactersToDouble(const UChar*, size_t, bool* ok = 0);
float charactersToFloat(const UChar*, size_t, bool* ok = 0);
+template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters(const UChar*, size_t);
+
class String {
public:
// Construct a null string, distinguishable from an empty string.
@@ -220,6 +223,7 @@ public:
String simplifyWhiteSpace() const;
String removeCharacters(CharacterMatchFunctionPtr) const;
+ template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const;
// Return the string with case folded for case insensitive comparison.
String foldCase() const;
@@ -423,7 +427,19 @@ inline void appendNumber(Vector<UChar>& vector, unsigned char number)
}
}
-struct StringHash;
+template<bool isSpecialCharacter(UChar)> inline bool isAllSpecialCharacters(const UChar* characters, size_t length)
+{
+ for (size_t i = 0; i < length; ++i) {
+ if (!isSpecialCharacter(characters[i]))
+ return false;
+ }
+ return true;
+}
+
+template<bool isSpecialCharacter(UChar)> inline bool String::isAllSpecialCharacters() const
+{
+ return WTF::isAllSpecialCharacters<isSpecialCharacter>(characters(), length());
+}
// StringHash is the default hash for String
template<typename T> struct DefaultHash;
@@ -440,17 +456,26 @@ template <> struct VectorTraits<String> : SimpleClassVectorTraits
using WTF::CString;
using WTF::String;
-
-using WTF::isSpaceOrNewline;
-using WTF::find;
-using WTF::reverseFind;
using WTF::append;
using WTF::appendNumber;
-using WTF::equal;
-using WTF::equalIgnoringCase;
using WTF::charactersAreAllASCII;
+using WTF::charactersToIntStrict;
+using WTF::charactersToUIntStrict;
+using WTF::charactersToInt64Strict;
+using WTF::charactersToUInt64Strict;
+using WTF::charactersToIntPtrStrict;
using WTF::charactersToInt;
-using WTF::charactersToFloat;
+using WTF::charactersToUInt;
+using WTF::charactersToInt64;
+using WTF::charactersToUInt64;
+using WTF::charactersToIntPtr;
using WTF::charactersToDouble;
+using WTF::charactersToFloat;
+using WTF::equal;
+using WTF::equalIgnoringCase;
+using WTF::find;
+using WTF::isAllSpecialCharacters;
+using WTF::isSpaceOrNewline;
+using WTF::reverseFind;
#endif
diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h
index d59439d..c755c6c 100644
--- a/JavaScriptCore/wtf/unicode/Unicode.h
+++ b/JavaScriptCore/wtf/unicode/Unicode.h
@@ -32,7 +32,7 @@
#elif USE(GLIB_UNICODE)
#include <wtf/unicode/glib/UnicodeGLib.h>
#elif USE(WINCE_UNICODE)
-#include <wtf/unicode/wince/UnicodeWince.h>
+#include <wtf/unicode/wince/UnicodeWinCE.h>
#else
#error "Unknown Unicode implementation"
#endif
diff --git a/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h b/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
index 1963576..f865ef1 100644
--- a/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h
+++ b/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
@@ -36,6 +36,7 @@
#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
+#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2)
#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index badab66..c9e2e1c 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -23,6 +23,8 @@
#ifndef WTF_UNICODE_QT4_H
#define WTF_UNICODE_QT4_H
+#include "UnicodeMacrosFromICU.h"
+
#include <QChar>
#include <QString>
@@ -63,49 +65,6 @@ typedef uint16_t UChar;
#endif
typedef uint32_t UChar32;
-// some defines from ICU
-// FIXME: This should use UnicodeMacrosFromICU.h instead!
-
-#define U_IS_BMP(c) ((UChar32)(c)<=0xffff)
-#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
-#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
-#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
-#define U16_GET_SUPPLEMENTARY(lead, trail) \
- (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
-
-#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
-#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
-#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2)
-
-#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
-#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
-#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
-#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
-
-#define U16_NEXT(s, i, length, c) { \
- (c)=(s)[(i)++]; \
- if(U16_IS_LEAD(c)) { \
- uint16_t __c2; \
- if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
- ++(i); \
- (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
- } \
- } \
-}
-
-#define U16_PREV(s, start, i, c) { \
- (c)=(s)[--(i)]; \
- if(U16_IS_TRAIL(c)) { \
- uint16_t __c2; \
- if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
- --(i); \
- (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
- } \
- } \
-}
-
-#define U_MASK(x) ((uint32_t)1<<(x))
-
namespace WTF {
namespace Unicode {
diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp
index 42f0ff8..b52b05c 100644
--- a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp
+++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "UnicodeWince.h"
+#include "UnicodeWinCE.h"
#include <wchar.h>
diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
index 3866568..8cc9580 100644
--- a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h
+++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
@@ -21,55 +21,15 @@
*
*/
-#ifndef UNICODE_WINCE_H
-#define UNICODE_WINCE_H
+#ifndef WTF_UnicodeWinCE_h
+#define WTF_UnicodeWinCE_h
+
+#include "UnicodeMacrosFromICU.h"
#include "ce_unicode.h"
#define TO_MASK(x) (1 << (x))
-// some defines from ICU needed one or two places
-// FIXME: This should use UnicodeMacrosFromICU.h instead!
-
-#define U_IS_BMP(c) ((UChar32)(c)<=0xffff)
-#define U16_IS_LEAD(c) (((c) & 0xfffffc00) == 0xd800)
-#define U16_IS_TRAIL(c) (((c) & 0xfffffc00) == 0xdc00)
-#define U16_SURROGATE_OFFSET ((0xd800 << 10UL) + 0xdc00 - 0x10000)
-#define U16_GET_SUPPLEMENTARY(lead, trail) \
- (((UChar32)(lead) << 10UL) + (UChar32)(trail) - U16_SURROGATE_OFFSET)
-
-#define U16_LEAD(supplementary) (UChar)(((supplementary) >> 10) + 0xd7c0)
-#define U16_TRAIL(supplementary) (UChar)(((supplementary) & 0x3ff) | 0xdc00)
-#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2)
-
-#define U_IS_SURROGATE(c) (((c) & 0xfffff800) == 0xd800)
-#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
-#define U16_IS_SURROGATE_LEAD(c) (((c) & 0x400) == 0)
-
-#define U16_NEXT(s, i, length, c) { \
- (c)=(s)[(i)++]; \
- if (U16_IS_LEAD(c)) { \
- uint16_t __c2; \
- if ((i) < (length) && U16_IS_TRAIL(__c2 = (s)[(i)])) { \
- ++(i); \
- (c) = U16_GET_SUPPLEMENTARY((c), __c2); \
- } \
- } \
-}
-
-#define U16_PREV(s, start, i, c) { \
- (c)=(s)[--(i)]; \
- if (U16_IS_TRAIL(c)) { \
- uint16_t __c2; \
- if ((i) > (start) && U16_IS_LEAD(__c2 = (s)[(i) - 1])) { \
- --(i); \
- (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \
- } \
- } \
-}
-
-#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
-
namespace WTF {
namespace Unicode {
@@ -216,5 +176,4 @@ namespace WTF {
} // namespace WTF
-#endif
-// vim: ts=2 sw=2 et
+#endif // WTF_UnicodeWinCE_h
diff --git a/JavaScriptCore/wtf/wince/FastMallocWince.h b/JavaScriptCore/wtf/wince/FastMallocWinCE.h
index 37174f0..d91a5f2 100644
--- a/JavaScriptCore/wtf/wince/FastMallocWince.h
+++ b/JavaScriptCore/wtf/wince/FastMallocWinCE.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef FastMallocWince_h
-#define FastMallocWince_h
+#ifndef WTF_FastMallocWinCE_h
+#define WTF_FastMallocWinCE_h
#include <new.h>
@@ -172,5 +172,4 @@ namespace WTF {
#endif
-#endif // FastMallocWince_h
-
+#endif // WTF_FastMallocWinCE_h
diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri
new file mode 100644
index 0000000..84ac20e
--- /dev/null
+++ b/JavaScriptCore/wtf/wtf.pri
@@ -0,0 +1,35 @@
+# wtf - qmake build info
+
+SOURCES += \
+ wtf/Assertions.cpp \
+ wtf/ByteArray.cpp \
+ wtf/CurrentTime.cpp \
+ wtf/DateMath.cpp \
+ wtf/dtoa.cpp \
+ wtf/FastMalloc.cpp \
+ wtf/HashTable.cpp \
+ wtf/MD5.cpp \
+ wtf/MainThread.cpp \
+ wtf/qt/MainThreadQt.cpp \
+ wtf/qt/StringQt.cpp \
+ wtf/qt/ThreadingQt.cpp \
+ wtf/PageAllocation.cpp \
+ wtf/RandomNumber.cpp \
+ wtf/RefCountedLeakCounter.cpp \
+ wtf/ThreadingNone.cpp \
+ wtf/Threading.cpp \
+ wtf/TypeTraits.cpp \
+ wtf/WTFThreadData.cpp \
+ wtf/text/AtomicString.cpp \
+ wtf/text/CString.cpp \
+ wtf/text/StringImpl.cpp \
+ wtf/text/StringStatics.cpp \
+ wtf/text/WTFString.cpp \
+ wtf/unicode/CollatorDefault.cpp \
+ wtf/unicode/icu/CollatorICU.cpp \
+ wtf/unicode/UTF8.cpp
+
+!contains(DEFINES, USE_SYSTEM_MALLOC) {
+ SOURCES += wtf/TCSystemAlloc.cpp
+}
+
diff --git a/JavaScriptCore/yarr/RegexCompiler.cpp b/JavaScriptCore/yarr/RegexCompiler.cpp
index fa87186..9f9e028 100644
--- a/JavaScriptCore/yarr/RegexCompiler.cpp
+++ b/JavaScriptCore/yarr/RegexCompiler.cpp
@@ -240,6 +240,7 @@ public:
RegexPatternConstructor(RegexPattern& pattern)
: m_pattern(pattern)
, m_characterClassConstructor(pattern.m_ignoreCase)
+ , m_invertParentheticalAssertion(false)
{
}
@@ -255,6 +256,11 @@ public:
void assertionBOL()
{
+ if (!m_alternative->m_terms.size() & !m_invertParentheticalAssertion) {
+ m_alternative->m_startsWithBOL = true;
+ m_alternative->m_containsBOL = true;
+ m_pattern.m_containsBOL = true;
+ }
m_alternative->m_terms.append(PatternTerm::BOL());
}
void assertionEOL()
@@ -358,15 +364,36 @@ public:
m_pattern.m_disjunctions.append(parenthesesDisjunction);
m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, invert));
m_alternative = parenthesesDisjunction->addNewAlternative();
+ m_invertParentheticalAssertion = invert;
}
void atomParenthesesEnd()
{
ASSERT(m_alternative->m_parent);
ASSERT(m_alternative->m_parent->m_parent);
+
+ PatternDisjunction* parenthesisDisjunction = m_alternative->m_parent;
m_alternative = m_alternative->m_parent->m_parent;
+
+ PatternTerm& lastTerm = m_alternative->lastTerm();
+
+ unsigned numParenAlternatives = parenthesisDisjunction->m_alternatives.size();
+ unsigned numBOLAnchoredAlts = 0;
+ // Bubble up BOL flags
+ for (unsigned i = 0; i < numParenAlternatives; i++) {
+ if (parenthesisDisjunction->m_alternatives[i]->m_startsWithBOL)
+ numBOLAnchoredAlts++;
+ }
+
+ if (numBOLAnchoredAlts) {
+ m_alternative->m_containsBOL = true;
+ // If all the alternatives in parens start with BOL, then so does this one
+ if (numBOLAnchoredAlts == numParenAlternatives)
+ m_alternative->m_startsWithBOL = true;
+ }
- m_alternative->lastTerm().parentheses.lastSubpatternId = m_pattern.m_numSubpatterns;
+ lastTerm.parentheses.lastSubpatternId = m_pattern.m_numSubpatterns;
+ m_invertParentheticalAssertion = false;
}
void atomBackReference(unsigned subpatternId)
@@ -397,32 +424,39 @@ public:
m_alternative->m_terms.append(PatternTerm(subpatternId));
}
- PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction)
+ // deep copy the argument disjunction. If filterStartsWithBOL is true,
+ // skip alternatives with m_startsWithBOL set true.
+ PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction, bool filterStartsWithBOL = false)
{
- PatternDisjunction* newDisjunction = new PatternDisjunction();
-
- newDisjunction->m_parent = disjunction->m_parent;
+ PatternDisjunction* newDisjunction = 0;
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
PatternAlternative* alternative = disjunction->m_alternatives[alt];
- PatternAlternative* newAlternative = newDisjunction->addNewAlternative();
- for (unsigned i = 0; i < alternative->m_terms.size(); ++i)
- newAlternative->m_terms.append(copyTerm(alternative->m_terms[i]));
+ if (!filterStartsWithBOL || !alternative->m_startsWithBOL) {
+ if (!newDisjunction) {
+ newDisjunction = new PatternDisjunction();
+ newDisjunction->m_parent = disjunction->m_parent;
+ }
+ PatternAlternative* newAlternative = newDisjunction->addNewAlternative();
+ for (unsigned i = 0; i < alternative->m_terms.size(); ++i)
+ newAlternative->m_terms.append(copyTerm(alternative->m_terms[i], filterStartsWithBOL));
+ }
}
-
- m_pattern.m_disjunctions.append(newDisjunction);
+
+ if (newDisjunction)
+ m_pattern.m_disjunctions.append(newDisjunction);
return newDisjunction;
}
-
- PatternTerm copyTerm(PatternTerm& term)
+
+ PatternTerm copyTerm(PatternTerm& term, bool filterStartsWithBOL = false)
{
if ((term.type != PatternTerm::TypeParenthesesSubpattern) && (term.type != PatternTerm::TypeParentheticalAssertion))
return PatternTerm(term);
-
+
PatternTerm termCopy = term;
- termCopy.parentheses.disjunction = copyDisjunction(termCopy.parentheses.disjunction);
+ termCopy.parentheses.disjunction = copyDisjunction(termCopy.parentheses.disjunction, filterStartsWithBOL);
return termCopy;
}
-
+
void quantifyAtom(unsigned min, unsigned max, bool greedy)
{
ASSERT(min <= max);
@@ -589,11 +623,40 @@ public:
setupDisjunctionOffsets(m_pattern.m_body, 0, 0);
}
+ void optimizeBOL()
+ {
+ // Look for expressions containing beginning of line (^) anchoring and unroll them.
+ // e.g. /^a|^b|c/ becomes /^a|^b|c/ which is executed once followed by /c/ which loops
+ // This code relies on the parsing code tagging alternatives with m_containsBOL and
+ // m_startsWithBOL and rolling those up to containing alternatives.
+ // At this point, this is only valid for non-multiline expressions.
+ PatternDisjunction* disjunction = m_pattern.m_body;
+
+ if (!m_pattern.m_containsBOL || m_pattern.m_multiline)
+ return;
+
+ PatternDisjunction* loopDisjunction = copyDisjunction(disjunction, true);
+
+ // Set alternatives in disjunction to "onceThrough"
+ for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt)
+ disjunction->m_alternatives[alt]->setOnceThrough();
+
+ if (loopDisjunction) {
+ // Move alternatives from loopDisjunction to disjunction
+ for (unsigned alt = 0; alt < loopDisjunction->m_alternatives.size(); ++alt)
+ disjunction->m_alternatives.append(loopDisjunction->m_alternatives[alt]);
+
+ loopDisjunction->m_alternatives.clear();
+ }
+ }
+
+
private:
RegexPattern& m_pattern;
PatternAlternative* m_alternative;
CharacterClassConstructor m_characterClassConstructor;
bool m_invertCharacterClass;
+ bool m_invertParentheticalAssertion;
};
@@ -621,6 +684,8 @@ const char* compileRegex(const UString& patternString, RegexPattern& pattern)
ASSERT(numSubpatterns == pattern.m_numSubpatterns);
}
+ constructor.optimizeBOL();
+
constructor.setupOffsets();
return 0;
diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp
index 7818b52..8740130 100644
--- a/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/JavaScriptCore/yarr/RegexJIT.cpp
@@ -1207,21 +1207,26 @@ class RegexGenerator : private MacroAssembler {
TermGenerationState state(disjunction, 0);
state.resetAlternative();
- // Plant a check to see if there is sufficient input available to run the first alternative.
- // Jumping back to the label 'firstAlternative' will get to this check, jumping to
- // 'firstAlternativeInputChecked' will jump directly to matching the alternative having
- // skipped this check.
-
- Label firstAlternative(this);
-
// 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;
+ }
countToCheckForFirstAlternative = alternative->m_minimumSize;
state.checkedTotal += countToCheckForFirstAlternative;
if (countToCheckForFirstAlternative)
@@ -1229,15 +1234,17 @@ class RegexGenerator : private MacroAssembler {
countCheckedForCurrentAlternative = countToCheckForFirstAlternative;
}
- Label firstAlternativeInputChecked(this);
+ if (setRepeatAlternativeLabels)
+ firstAlternativeInputChecked = Label(this);
while (state.alternativeValid()) {
- // Track whether any alternatives are shorter than the first one.
- hasShorterAlternatives = hasShorterAlternatives || (countCheckedForCurrentAlternative < countToCheckForFirstAlternative);
-
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);
@@ -1264,6 +1271,17 @@ class RegexGenerator : private MacroAssembler {
// if there are any more alternatives, plant the check for input before looping.
if (state.alternativeValid()) {
PatternAlternative* nextAlternative = state.alternative();
+ bool setAlternativeLoopLabel = false;
+ if (!setRepeatAlternativeLabels && !nextAlternative->onceThrough()) {
+ // We have handled non-repeating alternatives, jump to next iteration
+ // and loop over repeating alternatives.
+ state.jumpToBacktrack(jump(), this);
+
+ firstAlternative = Label(this);
+ setRepeatAlternativeLabels = true;
+ setAlternativeLoopLabel = true;
+ }
+
int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
@@ -1302,6 +1320,12 @@ class RegexGenerator : private MacroAssembler {
state.linkAlternativeBacktracks(this);
}
+ if (setAlternativeLoopLabel) {
+ firstAlternativeInputChecked = Label(this);
+ countToCheckForFirstAlternative = countToCheckForNextAlternative;
+ setAlternativeLoopLabel = true;
+ }
+
state.checkedTotal -= countCheckedForCurrentAlternative;
countCheckedForCurrentAlternative = countToCheckForNextAlternative;
state.checkedTotal += countCheckedForCurrentAlternative;
@@ -1312,75 +1336,83 @@ class RegexGenerator : private MacroAssembler {
state.checkedTotal -= countCheckedForCurrentAlternative;
- // 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);
- 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(firstAlternativeInputChecked, this);
- else { // no need to check the input, but we do have some bookkeeping to do first.
+ 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);
+ 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);
+ 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(firstAlternativeInputChecked, this);
+ else { // no need to check the input, but we do have some bookkeeping to do first.
+ state.linkAlternativeBacktracks(this);
- // 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));
- }
+ // 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));
+ }
- // Update index if necessary, and loop (without checking).
- if (incrementForNextIter)
- add32(Imm32(incrementForNextIter), index);
- jump().linkTo(firstAlternativeInputChecked, this);
- }
+ // Update index if necessary, and loop (without checking).
+ if (incrementForNextIter)
+ add32(Imm32(incrementForNextIter), index);
+ jump().linkTo(firstAlternativeInputChecked, this);
+ }
- 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));
+ 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));
+ }
+
+ // 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!)
}
- // 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!)
if (m_pattern.m_body->m_callFrameSize)
addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
diff --git a/JavaScriptCore/yarr/RegexPattern.h b/JavaScriptCore/yarr/RegexPattern.h
index 61d6ad6..eecbd43 100644
--- a/JavaScriptCore/yarr/RegexPattern.h
+++ b/JavaScriptCore/yarr/RegexPattern.h
@@ -207,6 +207,10 @@ struct PatternTerm {
struct PatternAlternative : FastAllocBase {
PatternAlternative(PatternDisjunction* disjunction)
: m_parent(disjunction)
+ , m_onceThrough(false)
+ , m_hasFixedSize(false)
+ , m_startsWithBOL(false)
+ , m_containsBOL(false)
{
}
@@ -221,16 +225,30 @@ struct PatternAlternative : FastAllocBase {
ASSERT(m_terms.size());
m_terms.shrink(m_terms.size() - 1);
}
+
+ void setOnceThrough()
+ {
+ m_onceThrough = true;
+ }
+
+ bool onceThrough()
+ {
+ return m_onceThrough;
+ }
Vector<PatternTerm> m_terms;
PatternDisjunction* m_parent;
unsigned m_minimumSize;
- bool m_hasFixedSize;
+ bool m_onceThrough : 1;
+ bool m_hasFixedSize : 1;
+ bool m_startsWithBOL : 1;
+ bool m_containsBOL : 1;
};
struct PatternDisjunction : FastAllocBase {
PatternDisjunction(PatternAlternative* parent = 0)
: m_parent(parent)
+ , m_hasFixedSize(false)
{
}
@@ -269,9 +287,10 @@ struct RegexPattern {
RegexPattern(bool ignoreCase, bool multiline)
: m_ignoreCase(ignoreCase)
, m_multiline(multiline)
+ , m_containsBackreferences(false)
+ , m_containsBOL(false)
, m_numSubpatterns(0)
, m_maxBackReference(0)
- , m_containsBackreferences(false)
, newlineCached(0)
, digitsCached(0)
, spacesCached(0)
@@ -294,6 +313,7 @@ struct RegexPattern {
m_maxBackReference = 0;
m_containsBackreferences = false;
+ m_containsBOL = false;
newlineCached = 0;
digitsCached = 0;
@@ -357,11 +377,12 @@ struct RegexPattern {
return nonwordcharCached;
}
- bool m_ignoreCase;
- bool m_multiline;
+ bool m_ignoreCase : 1;
+ bool m_multiline : 1;
+ bool m_containsBackreferences : 1;
+ bool m_containsBOL : 1;
unsigned m_numSubpatterns;
unsigned m_maxBackReference;
- bool m_containsBackreferences;
PatternDisjunction* m_body;
Vector<PatternDisjunction*, 4> m_disjunctions;
Vector<CharacterClass*> m_userCharacterClasses;