summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /JavaScriptCore
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/API/JSStringRef.h2
-rw-r--r--JavaScriptCore/ChangeLog800
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptCore/GNUmakefile.am15
-rw-r--r--JavaScriptCore/JavaScriptCore.exp2
-rw-r--r--JavaScriptCore/JavaScriptCore.pri3
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops2
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.cpp31
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h1
-rw-r--r--JavaScriptCore/bytecode/Opcode.cpp7
-rw-r--r--JavaScriptCore/bytecode/Opcode.h6
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp116
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h15
-rw-r--r--JavaScriptCore/bytecompiler/NodesCodegen.cpp17
-rwxr-xr-xJavaScriptCore/docs/make-bytecode-docs.pl1
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp100
-rw-r--r--JavaScriptCore/jit/JIT.cpp7
-rw-r--r--JavaScriptCore/jit/JIT.h7
-rw-r--r--JavaScriptCore/jit/JITCall32_64.cpp12
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp192
-rw-r--r--JavaScriptCore/jit/JITOpcodes32_64.cpp100
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp35
-rw-r--r--JavaScriptCore/jit/JITStubs.h7
-rw-r--r--JavaScriptCore/jsc.pro4
-rw-r--r--JavaScriptCore/os-win32/inttypes.h261
-rw-r--r--JavaScriptCore/parser/JSParser.cpp27
-rw-r--r--JavaScriptCore/parser/Nodes.h3
-rw-r--r--JavaScriptCore/qt/ChangeLog36
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.cpp23
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.h5
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.cpp14
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.h8
-rw-r--r--JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h11
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.cpp23
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.h3
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h35
-rw-r--r--JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp49
-rw-r--r--JavaScriptCore/runtime/Arguments.h2
-rw-r--r--JavaScriptCore/runtime/DateConstructor.cpp74
-rw-r--r--JavaScriptCore/runtime/Executable.cpp8
-rw-r--r--JavaScriptCore/runtime/Executable.h6
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp55
-rw-r--r--JavaScriptCore/runtime/JSActivation.h9
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp18
-rw-r--r--JavaScriptCore/runtime/JSCell.h19
-rw-r--r--JavaScriptCore/runtime/MathObject.cpp4
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp11
-rw-r--r--JavaScriptCore/wtf/Assertions.cpp7
-rw-r--r--JavaScriptCore/wtf/Noncopyable.h29
-rw-r--r--JavaScriptCore/wtf/PassRefPtr.h4
-rw-r--r--JavaScriptCore/wtf/Platform.h6
-rw-r--r--JavaScriptCore/wtf/RefCounted.h4
-rw-r--r--JavaScriptCore/wtf/StringHashFunctions.h227
-rw-r--r--JavaScriptCore/wtf/ThreadingPthreads.cpp8
-rw-r--r--JavaScriptCore/wtf/gobject/GOwnPtr.cpp4
-rw-r--r--JavaScriptCore/wtf/gobject/GOwnPtr.h5
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.cpp4
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.h4
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.cpp5
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.h4
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.h6
-rw-r--r--JavaScriptCore/wtf/unicode/UTF8.cpp2
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h2
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.cpp19
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.h11
-rw-r--r--JavaScriptCore/yarr/RegexJIT.cpp111
66 files changed, 2269 insertions, 381 deletions
diff --git a/JavaScriptCore/API/JSStringRef.h b/JavaScriptCore/API/JSStringRef.h
index 51871b1..c5c1544 100644
--- a/JavaScriptCore/API/JSStringRef.h
+++ b/JavaScriptCore/API/JSStringRef.h
@@ -38,7 +38,7 @@ extern "C" {
#endif
#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__) \
- && !((defined(__CC_ARM) || defined(__ARMCC__)) && defined(__SYMBIAN32__)) /* RVCT */
+ && !((defined(__CC_ARM) || defined(__ARMCC__)) && !defined(__linux__)) /* RVCT */
/*!
@typedef JSChar
@abstract A Unicode character.
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 045347a..bbdf703 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,803 @@
+2010-09-29 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Next try to fix cygwin build.
+
+ * wtf/Assertions.cpp:
+
+2010-09-29 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Build fix for cygwin #2. It's OS(WINDOWS), not OS(WIN).
+
+ * wtf/Assertions.cpp:
+
+2010-09-29 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Build fix for cygwin.
+
+ * wtf/Assertions.cpp:
+
+2010-09-29 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ [WINCE] Buildfix for Assertions.cpp after r68511.
+ https://bugs.webkit.org/show_bug.cgi?id=46807
+
+ Some, but not all WinCE environments have support for IsDebuggerPresent().
+ Add HAVE(ISDEBUGGERPRESENT) to make this a build option.
+ HAVE(ISDEBUGGERPRESENT) will be 1 for all OS(WIN) by default.
+
+ * wtf/Assertions.cpp:
+ * wtf/Platform.h:
+
+2010-09-29 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Csaba Osztrogonác.
+
+ JSC compile fails on 32bit platform when Regexp Tracing is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=46713
+
+ Fix the cast of pointer in regexp tracing to avoid the warning.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+
+2010-09-28 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Begin hooking up painting in the plug-in process
+ https://bugs.webkit.org/show_bug.cgi?id=46766
+
+ * JavaScriptCore.exp:
+ Add tryFastRealloc, used by WebKit2.
+
+2010-09-28 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ Guard GRefPtr/GOwnPtr files with ENABLE(GLIB_SUPPORT)
+ https://bugs.webkit.org/show_bug.cgi?id=46721
+
+ Enable GOwnPtr/GRefPtr build only if glib support has been
+ explicitly enabled using the WTF_ENABLE_GLIB_SUPPORT macro.
+
+ * wtf/gobject/GOwnPtr.cpp:
+ * wtf/gobject/GOwnPtr.h:
+ * wtf/gobject/GRefPtr.cpp:
+ * wtf/gobject/GRefPtr.h:
+
+2010-09-28 İsmail Dönmez <ismail@namtrac.org>
+
+ Reviewed by Andreas Kling.
+
+ Test for WINCE instead of WINCEBASIC, compiler always defines WINCE.
+ Remove reference to unexisting path JavaScriptCore/os-wince.
+
+ * JavaScriptCore.pri:
+ * wtf/Assertions.cpp:
+
+2010-09-27 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Changed the initialization of JSArray objects to have space for
+ 3 elements for the constructor that takes a ArgList argument.
+ This improves v8-deltablue performance by about 2.8% by reducing
+ the number of realloc() calls.
+ https://bugs.webkit.org/show_bug.cgi?id=46664
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray):
+
+2010-09-27 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 46680 - Inlining string concatenation can regress interpreter performance
+ <rdar://problem/8362752> REGRESSION: ~6.4% sunspider regression in interpreter
+ Do not inline calls to string concatenation in the interpret loop.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::concatenateStrings):
+ (JSC::Interpreter::privateExecute):
+
+2010-09-27 Anders Carlsson <andersca@apple.com>
+
+ Fix thinko.
+
+ * runtime/JSCell.h:
+
+2010-09-27 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Try to fix Windows build.
+
+ * runtime/JSCell.h:
+ (JSC::MSVCBugWorkaround::MSVCBugWorkaround):
+ (JSC::MSVCBugWorkaround::~MSVCBugWorkaround):
+
+2010-09-27 Erik Arvidsson <arv@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Add operator == for AtomicString and Vector<Uchar>
+ https://bugs.webkit.org/show_bug.cgi?id=46509
+
+ * JavaScriptCore.exp:
+ * wtf/text/AtomicString.cpp:
+ (WTF::operator==):
+ * wtf/text/AtomicString.h:
+ (WTF::operator==):
+ (WTF::operator!=):
+
+2010-09-27 Anders Carlsson <andersca@apple.com>
+
+ Try to fix the Windows build.
+
+ * wtf/Noncopyable.h:
+
+2010-09-26 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Alexey Proskuryakov and Adam Barth.
+
+ Add WTF_MAKE_NONCOPYABLE macro
+ https://bugs.webkit.org/show_bug.cgi?id=46589
+
+ Going forward, we'd like to get rid of the Noncopyable and FastAllocBase classes. The
+ reason for this is that the Itanium C++ ABI states that no empty classes of the same type
+ can be laid out at the same offset in the class. This can result in objects getting larger
+ which leads to memory regressions. (One example of this is the String class which grew by
+ sizeof(void*) when both its base class and its first member variable inherited indirectly
+ from FastAllocBase).
+
+ * wtf/Noncopyable.h:
+ Add a WTF_MAKE_NONCOPYABLE macro and get rid of NoncopyableCustomAllocated.
+
+ * runtime/JSCell.h:
+ * wtf/RefCounted.h:
+ Don't inherit from NoncopyableCustomAllocated. Instead, use WTF_MAKE_NONCOPYABLE.
+
+2010-09-27 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] use ENABLE(GLIB_SUPPORT)
+ https://bugs.webkit.org/show_bug.cgi?id=46630
+
+ * wtf/Platform.h: Include GTypedefs.h only if glib support
+ is explicitly enabled.
+
+2010-09-25 Holger Hans Peter Freyther <holger@moiji-mobile.com>
+
+ Reviewed by Adam Barth.
+
+ jsc: Document the strcat opcode.
+ https://bugs.webkit.org/show_bug.cgi?id=46571
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-09-21 Holger Hans Peter Freyther <holger@moiji-mobile.com>
+
+ Reviewed by Adam Barth.
+
+ make-bytecode-docs.pl: Add a comment to the generated HTML
+ https://bugs.webkit.org/show_bug.cgi?id=46570
+
+ Generate an HTML Comment that this file was generated from
+ Interpreter.cpp with the make-bytecode-docs.pl script.
+
+ * docs/make-bytecode-docs.pl:
+
+2010-09-27 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Remove WTF::stringHash functions
+ https://bugs.webkit.org/show_bug.cgi?id=46520
+
+ Since r68289 the stringHash functions are only wrappers around StringHasher::createHash.
+ So use StringHasher::createHash directly and remove stringHash.
+
+ * wtf/StringHashFunctions.h:
+ * wtf/text/StringImpl.h:
+ (WTF::StringImpl::computeHash): Use WTF::StringHasher::createHash directly.
+
+2010-09-26 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add WTF::StringHasher::createBlobHash
+ https://bugs.webkit.org/show_bug.cgi?id=46514
+
+ Add this function for hashing FormElementKey and QualifiedNameComponents.
+
+ * wtf/StringHashFunctions.h:
+ (WTF::StringHasher::createBlobHash):
+
+2010-09-26 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ REGRESSION (r68289): Assertion failure in StringHasher::addCharacter() (ch != invalidCharacterValue)
+ running websocket/tests/bad-sub-protocol-non-ascii.html
+ https://bugs.webkit.org/show_bug.cgi?id=46553
+
+ Because we use StringHasher for binary data too, so the check for invalid unicode input is wrong.
+ Add an additional member variable to indicate if we have an pending character
+ instead of only using an invalid character for this purpose.
+
+ * wtf/StringHashFunctions.h:
+ (WTF::StringHasher::StringHasher):
+ (WTF::StringHasher::addCharacters):
+ (WTF::StringHasher::addCharacter):
+ (WTF::StringHasher::hash):
+
+2010-09-26 Mark Hahnenberg <mhahnenb@gmail.com>
+
+ Reviewed by Oliver Hunt.
+
+ valueOf called in wrong order in atan2 and date constructors.
+ https://bugs.webkit.org/show_bug.cgi?id=26978
+
+ Fixed the bug where the arguments to atan2 were being evaluated
+ out of order.
+
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncATan2):
+
+2010-09-26 Mark Hahnenberg <mhahnenb@gmail.com>
+
+ Reviewed by Oliver Hunt.
+
+ valueOf called in wrong order in atan2 and date constructors.
+ https://bugs.webkit.org/show_bug.cgi?id=26978
+
+ Fixed the issue where the parameters to the Date constructor
+ were being evaluated to numbers more than once.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::dateUTC):
+
+2010-09-25 Oliver Hunt <oliver@apple.com>
+
+ Fix various builds
+
+ Relearning the lesson that last minute changes are bad.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitGetArgumentsLength):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emitSlow_op_get_argument_by_val):
+
+2010-09-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Avoid constructing arguments object when accessing length and index properties
+ https://bugs.webkit.org/show_bug.cgi?id=46572
+
+ Add opcodes to read argument length and properties, and then implement them.
+ Much like other lazy opcodes these opcodes take a fast path when the arguments
+ object has not been instantiated, and fall back on generic access mechanisms
+ if they are acting on an instantiated object.
+
+ 3% win on v8-earleyboyer, no change elsewhere.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitGetArgumentsLength):
+ (JSC::BytecodeGenerator::emitGetArgumentByVal):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BracketAccessorNode::emitBytecode):
+ (JSC::DotAccessorNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emitSlow_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::emitSlow_op_get_argument_by_val):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emitSlow_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::emitSlow_op_get_argument_by_val):
+
+2010-09-25 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Fix typo in StringHasher class
+ https://bugs.webkit.org/show_bug.cgi?id=45970
+
+ * wtf/StringHashFunctions.h:
+ (WTF::StringHasher::createHash):
+
+2010-09-24 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Add WTF::StringHasher
+ https://bugs.webkit.org/show_bug.cgi?id=45970
+
+ StringHasher is a class for calculation stringHash out of character string.
+ This class will unify the different usages of the same algorithm.
+
+ * wtf/StringHashFunctions.h:
+ (WTF::StringHasher::StringHasher):
+ (WTF::StringHasher::addCharacters):
+ (WTF::StringHasher::addCharacter):
+ (WTF::StringHasher::hash):
+ (WTF::StringHasher::createHash):
+ (WTF::StringHasher::defaultCoverter):
+ (WTF::StringHasher::addCharactersToHash):
+ (WTF::stringHash):
+
+2010-09-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Variable declarations inside a catch scope don't get propogated to the parent scope
+ https://bugs.webkit.org/show_bug.cgi?id=46501
+
+ Add logic to make variable declaration look for a scope for the
+ new variable. This allows us to create a scope (eg. for catch)
+ and then seal it, so that additional variable declarations
+ contained are propogated to the correct target. Strangely this
+ comes out as a performance win, but I think it's mostly cache
+ effects.
+
+ * parser/JSParser.cpp:
+ (JSC::JSParser::Scope::Scope):
+ (JSC::JSParser::Scope::preventNewDecls):
+ (JSC::JSParser::Scope::allowsNewDecls):
+ (JSC::JSParser::declareVariable):
+ (JSC::JSParser::parseVarDeclarationList):
+ (JSC::JSParser::parseConstDeclarationList):
+ (JSC::JSParser::parseTryStatement):
+ (JSC::JSParser::parseFormalParameters):
+ (JSC::JSParser::parseFunctionDeclaration):
+
+2010-09-24 İsmail Dönmez <ismail@namtrac.org>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Add a Windows compatible inttypes.h header to fix WinCE build.
+ https://bugs.webkit.org/show_bug.cgi?id=46463
+
+ * os-win32/inttypes.h: Added.
+
+2010-09-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ REGRESSION(r68223): It broke 2-3 tests on bots (Requested by Ossy on #webkit).
+ https://bugs.webkit.org/show_bug.cgi?id=46448
+
+ Roll this back in, with additional logic to prevent us from delaying construction
+ of functions named "arguments"
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitInitLazyRegister):
+ (JSC::BytecodeGenerator::registerFor):
+ (JSC::BytecodeGenerator::createLazyRegisterIfNecessary):
+ (JSC::BytecodeGenerator::constRegisterFor):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ (JSC::BytecodeGenerator::emitLazyNewFunction):
+ (JSC::BytecodeGenerator::emitNewFunctionInternal):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_init_lazy_reg):
+ (JSC::JIT::emit_op_new_func):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_init_lazy_reg):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::needsActivationForMoreThanVariables):
+
+2010-09-23 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r68223.
+ http://trac.webkit.org/changeset/68223
+ https://bugs.webkit.org/show_bug.cgi?id=46448
+
+ It broke 2-3 tests on bots (Requested by Ossy on #webkit).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::registerFor):
+ (JSC::BytecodeGenerator::constRegisterFor):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_func):
+ (JSC::JIT::emit_op_init_arguments):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_new_func):
+ (JSC::JIT::emit_op_init_arguments):
+ * parser/Nodes.h:
+
+2010-09-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Delay construction of functions that aren't captured
+ https://bugs.webkit.org/show_bug.cgi?id=46433
+
+ If a function isn't captured by an activation there's no
+ way it can be accessed indirectly, so we can delay the
+ construction until it's used (similar to what we do with
+ arguments). We rename the existing op_init_arguments to
+ op_init_lazy_reg and removed its implicit handling of
+ the anonymous argument register, and make op_new_function
+ take a parameter to indicate whether it should null check
+ the target slot before creating the function object.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitInitLazyRegister):
+ (JSC::BytecodeGenerator::registerFor):
+ (JSC::BytecodeGenerator::createLazyRegisterIfNecessary):
+ (JSC::BytecodeGenerator::constRegisterFor):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ (JSC::BytecodeGenerator::emitLazyNewFunction):
+ (JSC::BytecodeGenerator::emitNewFunctionInternal):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_init_lazy_reg):
+ (JSC::JIT::emit_op_new_func):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_init_lazy_reg):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::needsActivationForMoreThanVariables):
+
+2010-09-23 David Kilzer <ddkilzer@apple.com>
+
+ <rdar://problem/8460731> ~9.9% speedup when compiling interpreter with llvm-gcc-4.2
+ https://bugs.webkit.org/show_bug.cgi?id=46423
+
+ Reviewed by Oliver Hunt.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute): Disable the gcc computed
+ goto hacks added in r55564 when compiling with llvm-gcc-4.2.
+
+2010-09-23 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Darin Adler.
+
+ Fix usage of enum as if it was a define
+ https://bugs.webkit.org/show_bug.cgi?id=46355
+
+ pthread.h defines PTHREAD_MUTEX_DEFAULT and PTHREAD_MUTEX_NORMAL as an
+ enum. Hence, it cannot be used by the preprocessor which always
+ evaluates that condition as true. This was giving a warning when
+ compiling with gcc and "-Wundef" flag.
+
+ The second path, when PTHREAD_MUTEX_DEFAULT is not the same of
+ PTHREAD_MUTEX_NORMAL, is not slow. So, let's eliminate the first path
+ and get rid of that #if.
+
+ * wtf/ThreadingPthreads.cpp: Always call pthread_mutexattr_init() to
+ set mutex type to PTHREAD_MUTEX_NORMAL.
+ (WTF::Mutex::Mutex):
+
+2010-09-23 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Removed extraneous truncation of ovector on entry and error exit.
+ Changed the initialization to -1 of vector to only initialize
+ the start indecies, which is sufficient for the pattern/subpatterns.
+ Changed the JIT code to not clear the end index for subpatterns
+ as it isn't needed. These changes are worth ~2.7% on v8-regexp.
+ https://bugs.webkit.org/show_bug.cgi?id=46404
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateParenthesesSingle):
+
+2010-09-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Only copy captured variables into activation
+ https://bugs.webkit.org/show_bug.cgi?id=46330
+
+ We now track free variable information which means that
+ we no longer need to copy every variable defined in a
+ function. With this patch activations only retain those
+ variables needed for correctness. In order to interact
+ safely with the inspector this means that JSActivation
+ now provides its own lookup functions so it can avoid
+ trying to read or write to variables that have been
+ optimised out.
+
+ * bytecode/CodeBlock.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::capturedVariableCount):
+ (JSC::ScopeNode::captures):
+ * runtime/Arguments.h:
+ (JSC::JSActivation::copyRegisters):
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * runtime/Executable.h:
+ (JSC::FunctionExecutable::capturedVariableCount):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::markChildren):
+ (JSC::JSActivation::symbolTableGet):
+ (JSC::JSActivation::symbolTablePut):
+ (JSC::JSActivation::getOwnPropertyNames):
+ (JSC::JSActivation::symbolTablePutWithAttributes):
+ * runtime/JSActivation.h:
+
+2010-09-23 Ismail Donmez <ismail@namtrac.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix jsc.exe build for Windows CE
+
+ * jsc.pro: Add mmtimer.lib for Windows CE.
+
+2010-09-23 Ismail Donmez <ismail@namtrac.org>
+
+ Unreviewed.
+
+ JIT should be disabled on Windows CE. Broken in r64176.
+
+ * wtf/Platform.h:
+
+2010-09-23 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Reduce the number of BOL checks in YARR Interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=46260
+
+ Extend the YARR Interpreter with an optimization which reduces the number of
+ BOL assertion checks. If a "TypeBodyAlternative" byteTerm is followed by a
+ "TypeAssertionBOL" byteTerm it will be checked just one time.
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::Interpreter::matchDisjunction):
+ (JSC::Yarr::ByteCompiler::compile):
+ (JSC::Yarr::ByteCompiler::regexBegin):
+ (JSC::Yarr::ByteCompiler::alternativeBodyDisjunction):
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+ * yarr/RegexInterpreter.h:
+ (JSC::Yarr::ByteTerm::BodyAlternativeBegin):
+ (JSC::Yarr::ByteTerm::BodyAlternativeDisjunction):
+ (JSC::Yarr::ByteTerm::BodyAlternativeEnd):
+ (JSC::Yarr::ByteTerm::AlternativeBegin):
+ (JSC::Yarr::ByteTerm::AlternativeDisjunction):
+ (JSC::Yarr::ByteTerm::AlternativeEnd):
+
+2010-09-22 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fixed the cross over from alternatives executed once and
+ those that loop. This fixed the problem where the index
+ was getting messed up for looping alternatives causing an
+ infinite loop.
+ https://bugs.webkit.org/show_bug.cgi?id=46189
+
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateDisjunction):
+
+2010-09-22 Steve Falkenburg <sfalken@apple.com>
+
+ Rubber stamped by Jon Honeycutt.
+
+ Allow jsc.exe to be run against unversioned ICU.
+
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops:
+
+2010-09-22 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Laszlo Gombos.
+
+ Use "typedef wchar_t JSChar" when compiled with RVCT
+ https://bugs.webkit.org/show_bug.cgi?id=40651
+
+ Use wchar_t for JSChar and UChar when compiled with RVCT.
+ Linux is the exception for this rule.
+
+ * API/JSStringRef.h:
+ * wtf/unicode/qt4/UnicodeQt4.h:
+
+2010-09-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [INTERPRETER] Two tests fail with SputnikError: #1.1: if argArray is neither an array nor an arguments object (see 10.1.8), a TypeError exception is thrown
+ https://bugs.webkit.org/show_bug.cgi?id=44245
+
+ Remove incorrect code from op_load_varargs in the interpreter.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-09-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [JIT] fast/js/sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.5/S15.3.5.3_A2_T6.html fails
+ https://bugs.webkit.org/show_bug.cgi?id=44246
+
+ JIT code generated for instanceof was not checking to ensure that the prototype property was
+ an object, this patch ensures that it does.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+
+2010-09-22 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Inline UTF8SequenceLength
+ https://bugs.webkit.org/show_bug.cgi?id=45589
+
+ * wtf/unicode/UTF8.cpp:
+ (WTF::Unicode::convertUTF8ToUTF16): Use inline version of UTF8SequenceLength to improve performance.
+
+2010-09-21 Oliver Hunt <oliver@apple.com>
+
+ RS=Gavin Barraclough.
+
+ Fix codeblock dumping
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::ScriptExecutable):
+
+2010-09-21 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Speed up function.apply(..., arguments)
+ https://bugs.webkit.org/show_bug.cgi?id=46207
+
+ Add code to do argument copying inline in the case
+ where we're using Function.apply to forward our arguments
+ directly.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ Splitted op_load_varargs into fast and slow paths, so add the call
+ to the slow path generator.
+ * jit/JIT.h:
+ * jit/JITCall32_64.cpp:
+ Remove 32bit specific emit_op_load_varargs as the logic is the
+ same for all value representations
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_load_varargs):
+ Copy arguments inline
+ (JSC::JIT::emitSlow_op_load_varargs):
+
+2010-09-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/8363003> REGRESSION: ~1.4% sunspider regression in
+ interpreter due to 54724 and 54596
+
+ Fixed a typo (using "UNLIKELY" instead of "LIKELY").
+
+ * wtf/PassRefPtr.h:
+ (WTF::refIfNotNull):
+ (WTF::derefIfNotNull): It is likely that m_ptr != 0 because most RefPtrs
+ hold real data. Also, in cases where they do not hold real data, the
+ compiler usually sees a call to release() right before the call to the
+ destructor, so it can probably optimize out the test completely.
+
+2010-09-21 Fridrich Strba <fridrich.strba@bluewin.ch>
+
+ Reviewed by Martin Robinson.
+
+ Build issues with Windows versions of the GTK+ port
+ https://bugs.webkit.org/show_bug.cgi?id=45844
+
+ Link with winmm.dll when necessary and specify the executable extension
+ explicitely so that the Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@
+ rule actually works.
+
+ Don't try to build the ThreadSpecificWin.cpp since GTK+ port uses
+ a section in ThreadSpecific.cpp
+
+ * GNUmakefile.am:
+
+2010-09-21 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] 'make dist' should be fixed in preparation for the next release
+ https://bugs.webkit.org/show_bug.cgi?id=46129
+
+ * GNUmakefile.am: Update the sources list to include missing headers.
+
+2010-09-21 Dave Tapuska <dtapuska@rim.com>
+
+ Reviewed by Csaba Osztrogonác.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45673
+
+ r65596 caused ENABLE_PROFILER_REFERENCE_OFFSET to not be
+ 8 byte aligned. A non 8 byte divisible value for this will
+ cause the sp to become non 8 byte aligned.
+
+ Verify and correct offset values that r65596 effected that
+ weren't updated.
+
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+
+2010-09-21 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ Fix Opcode stats compilation
+ https://bugs.webkit.org/show_bug.cgi?id=46079
+
+ The FixedArray API had changed, and <stdio.h> was not included for
+ printf.
+
+ * bytecode/Opcode.cpp:
+ (JSC::OpcodeStats::~OpcodeStats):
+
2010-09-20 Michael Saboff <msaboff@apple.com>
Reviewed by Gavin Barraclough.
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index e82e464..f688ea8 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 = 9;
+MINOR_VERSION = 10;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index dd2ba21..88d1761 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -546,7 +546,6 @@ javascriptcore_sources += \
if TARGET_WIN32
javascriptcore_sources += \
- JavaScriptCore/wtf/ThreadSpecificWin.cpp \
JavaScriptCore/runtime/MarkStackWin.cpp
else
javascriptcore_sources += \
@@ -568,9 +567,9 @@ endif # USE_ICU_UNICODE
# ----
if USE_GLIB_UNICODE
javascriptcore_sources += \
+ JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h \
JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \
- JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp \
- JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h
+ JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp
endif
JavaScriptCore/Lexer.lut.h: $(srcdir)/JavaScriptCore/create_hash_table $(srcdir)/JavaScriptCore/parser/Keywords.table
@@ -586,7 +585,7 @@ JavaScriptCore/pcre/chartables.c: $(srcdir)/JavaScriptCore/pcre/dftables
$(AM_V_GEN)$(PERL) $^ $@
bin_PROGRAMS += \
- Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@
+ Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@$(EXEEXT)
noinst_PROGRAMS += \
Programs/jsc \
@@ -616,6 +615,7 @@ Programs_minidom_CFLAGS = \
Programs_minidom_LDADD = \
libJavaScriptCore.la \
+ $(WINMM_LIBS) \
-lm \
-lstdc++
@@ -624,8 +624,8 @@ Programs_minidom_LDFLAGS = \
-no-fast-install
# jsc
-Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@: Programs/jsc
- $(AM_V_GEN)cp -f Programs/jsc Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@
+Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@$(EXEEXT): Programs/jsc$(EXEEXT)
+ $(AM_V_GEN)cp -f Programs/jsc$(EXEEXT) Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@$(EXEEXT)
Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_LDADD =
Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_SOURCES =
@@ -644,7 +644,8 @@ Programs_jsc_CXXFLAGS = \
$(UNICODE_CFLAGS)
Programs_jsc_LDADD = \
- libJavaScriptCore.la
+ libJavaScriptCore.la \
+ $(WINMM_LIBS)
EXTRA_DIST += \
JavaScriptCore/AUTHORS \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 13b9676..ff3d9b3 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -380,6 +380,7 @@ __ZN3WTF13tryFastCallocEmm
__ZN3WTF13tryFastMallocEm
__ZN3WTF14fastMallocSizeEPKv
__ZN3WTF14numberToStringEdPt
+__ZN3WTF14tryFastReallocEPvm
__ZN3WTF15ThreadCondition4waitERNS_5MutexE
__ZN3WTF15ThreadCondition6signalEv
__ZN3WTF15ThreadCondition9broadcastEv
@@ -474,6 +475,7 @@ __ZN3WTF9dayInYearEdi
__ZN3WTF9emptyAtomE
__ZN3WTF9xmlnsAtomE
__ZN3WTFeqERKNS_12AtomicStringEPKc
+__ZN3WTFeqERKNS_12AtomicStringERKNS_6VectorItLm0EEE
__ZN3WTFeqERKNS_7CStringES2_
__ZN3WTFplEPKcRKNS_6StringE
__ZN3WTFplERKNS_6StringEPKc
diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index 8ef9b30..57b1ce8 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -56,9 +56,6 @@ DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
wince* {
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat
- DEFINES += WINCEBASIC
-
- INCLUDEPATH += $$PWD/../JavaScriptCore/os-wince
INCLUDEPATH += $$PWD/../JavaScriptCore/os-win32
}
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
index e5cc866..b63729c 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
+++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
@@ -19,7 +19,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;cmd /c&#x0D;&#x0A;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt44.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt44.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt44$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt44$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\libicuin$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libicuin$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\libicuuc$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libicuuc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;cmd /c&#x0D;&#x0A;"
/>
<Tool
Name="VCPreBuildEventTool"
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
index 0749cf6..6c0696e 100644
--- a/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -495,9 +495,9 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data());
break;
}
- case op_init_arguments: {
+ case op_init_lazy_reg: {
int r0 = (++it)->u.operand;
- printf("[%4d] init_arguments\t %s\n", location, registerName(exec, r0).data());
+ printf("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data());
break;
}
case op_get_callee: {
@@ -712,16 +712,16 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_resolve_global: {
int r0 = (++it)->u.operand;
- JSValue scope = JSValue((++it)->u.jsCell);
int id0 = (++it)->u.operand;
- printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data());
+ printf("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
it += 2;
break;
}
case op_resolve_global_dynamic: {
int r0 = (++it)->u.operand;
- JSValue scope = JSValue((++it)->u.jsCell);
int id0 = (++it)->u.operand;
+ JSValue scope = JSValue((++it)->u.jsCell);
+ ++it;
int depth = it[2].u.operand;
printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
it += 3;
@@ -743,16 +743,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_get_global_var: {
int r0 = (++it)->u.operand;
- JSValue scope = JSValue((++it)->u.jsCell);
int index = (++it)->u.operand;
- printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), index);
+ printf("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index);
break;
}
case op_put_global_var: {
- JSValue scope = JSValue((++it)->u.jsCell);
int index = (++it)->u.operand;
int r0 = (++it)->u.operand;
- printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).utf8().data(), index, registerName(exec, r0).data());
+ printf("[%4d] put_global_var\t %d, %s\n", location, index, registerName(exec, r0).data());
break;
}
case op_resolve_base: {
@@ -844,6 +842,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printGetByIdOp(exec, location, it, "get_string_length");
break;
}
+ case op_get_arguments_length: {
+ printUnaryOp(exec, location, it, "get_arguments_length");
+ it++;
+ break;
+ }
case op_put_by_id: {
printPutByIdOp(exec, location, it, "put_by_id");
break;
@@ -892,6 +895,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
break;
}
+ case op_get_argument_by_val: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int r2 = (++it)->u.operand;
+ printf("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
+ break;
+ }
case op_get_by_pname: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -1030,7 +1040,8 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_new_func: {
int r0 = (++it)->u.operand;
int f0 = (++it)->u.operand;
- printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(exec, r0).data(), f0);
+ int shouldCheck = (++it)->u.operand;
+ printf("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
break;
}
case op_new_func_exp: {
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
index 766ad2a..cda4530 100644
--- a/JavaScriptCore/bytecode/CodeBlock.h
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -514,6 +514,7 @@ namespace JSC {
int m_numCalleeRegisters;
int m_numVars;
+ int m_numCapturedVars;
int m_numParameters;
bool m_isConstructor;
diff --git a/JavaScriptCore/bytecode/Opcode.cpp b/JavaScriptCore/bytecode/Opcode.cpp
index 8f7f01f..0bb714b 100644
--- a/JavaScriptCore/bytecode/Opcode.cpp
+++ b/JavaScriptCore/bytecode/Opcode.cpp
@@ -30,6 +30,11 @@
#include "config.h"
#include "Opcode.h"
+#if ENABLE(OPCODE_STATS)
+#include <stdio.h>
+#include <wtf/FixedArray.h>
+#endif
+
using namespace std;
namespace JSC {
@@ -104,7 +109,7 @@ OpcodeStats::~OpcodeStats()
FixedArray<int, numOpcodeIDs> sortedIndices;
for (int i = 0; i < numOpcodeIDs; ++i)
sortedIndices[i] = i;
- qsort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices);
+ qsort(sortedIndices.data(), numOpcodeIDs, sizeof(int), compareOpcodeIndices);
pair<int, int> sortedPairIndices[numOpcodeIDs * numOpcodeIDs];
pair<int, int>* currentPairIndex = sortedPairIndices;
diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h
index 4563ebe..03f6573 100644
--- a/JavaScriptCore/bytecode/Opcode.h
+++ b/JavaScriptCore/bytecode/Opcode.h
@@ -40,7 +40,7 @@ namespace JSC {
#define FOR_EACH_OPCODE_ID(macro) \
macro(op_enter, 1) \
macro(op_enter_with_activation, 2) \
- macro(op_init_arguments, 2) \
+ macro(op_init_lazy_reg, 2) \
macro(op_create_arguments, 2) \
macro(op_create_this, 3) \
macro(op_get_callee, 2) \
@@ -120,12 +120,14 @@ namespace JSC {
macro(op_get_by_id_generic, 8) \
macro(op_get_array_length, 8) \
macro(op_get_string_length, 8) \
+ macro(op_get_arguments_length, 4) \
macro(op_put_by_id, 9) \
macro(op_put_by_id_transition, 9) \
macro(op_put_by_id_replace, 9) \
macro(op_put_by_id_generic, 9) \
macro(op_del_by_id, 4) \
macro(op_get_by_val, 4) \
+ macro(op_get_argument_by_val, 4) \
macro(op_get_by_pname, 7) \
macro(op_put_by_val, 4) \
macro(op_del_by_val, 4) \
@@ -153,7 +155,7 @@ namespace JSC {
macro(op_switch_char, 4) \
macro(op_switch_string, 4) \
\
- macro(op_new_func, 3) \
+ macro(op_new_func, 4) \
macro(op_new_func_exp, 3) \
macro(op_call, 4) \
macro(op_call_eval, 4) \
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index ab259a6..986709b 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -214,6 +214,8 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
, m_nextGlobalIndex(-1)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_firstLazyFunction(0)
+ , m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
@@ -287,6 +289,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
preserveLastVar();
}
+ codeBlock->m_numCapturedVars = codeBlock->m_numVars;
}
BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
@@ -303,6 +306,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
, m_codeType(FunctionCode)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_firstLazyFunction(0)
+ , m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
, m_emitNodeDepth(0)
@@ -334,8 +339,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
codeBlock->setArgumentsRegister(argumentsRegister->index());
ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
- emitOpcode(op_init_arguments);
- instructions().append(argumentsRegister->index());
+ emitInitLazyRegister(argumentsRegister);
+ emitInitLazyRegister(unmodifiedArgumentsRegister);
// The debugger currently retrieves the arguments object from an activation rather than pulling
// it from a call frame. In the long-term it should stop doing that (<rdar://problem/6911886>),
@@ -347,16 +352,54 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
}
const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
+ const DeclarationStacks::VarStack& varStack = functionBody->varStack();
+
+ // Captured variables and functions go first so that activations don't have
+ // to step over the non-captured locals to mark them.
+ if (functionBody->hasCapturedVariables()) {
+ for (size_t i = 0; i < functionStack.size(); ++i) {
+ FunctionBodyNode* function = functionStack[i];
+ const Identifier& ident = function->ident();
+ if (functionBody->captures(ident)) {
+ m_functions.add(ident.impl());
+ emitNewFunction(addVar(ident, false), function);
+ }
+ }
+ for (size_t i = 0; i < varStack.size(); ++i) {
+ const Identifier& ident = *varStack[i].first;
+ if (functionBody->captures(ident))
+ addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
+ }
+ }
+ bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables();
+ codeBlock->m_numCapturedVars = codeBlock->m_numVars;
+ m_firstLazyFunction = codeBlock->m_numVars;
for (size_t i = 0; i < functionStack.size(); ++i) {
FunctionBodyNode* function = functionStack[i];
const Identifier& ident = function->ident();
- m_functions.add(ident.impl());
- emitNewFunction(addVar(ident, false), function);
+ if (!functionBody->captures(ident)) {
+ m_functions.add(ident.impl());
+ RefPtr<RegisterID> reg = addVar(ident, false);
+ // Don't lazily create functions that override the name 'arguments'
+ // as this would complicate lazy instantiation of actual arguments.
+ if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
+ emitNewFunction(reg.get(), function);
+ else {
+ emitInitLazyRegister(reg.get());
+ m_lazyFunctions.set(reg->index(), function);
+ }
+ }
}
-
- const DeclarationStacks::VarStack& varStack = functionBody->varStack();
- for (size_t i = 0; i < varStack.size(); ++i)
- addVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
+ m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
+ for (size_t i = 0; i < varStack.size(); ++i) {
+ const Identifier& ident = *varStack[i].first;
+ if (!functionBody->captures(ident))
+ addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
+ }
+
+ if (debugger)
+ codeBlock->m_numCapturedVars = codeBlock->m_numVars;
+
FunctionParameters& parameters = *functionBody->parameters();
size_t parameterCount = parameters.size();
@@ -405,6 +448,8 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
, m_codeType(EvalCode)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_firstLazyFunction(0)
+ , m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
, m_emitNodeDepth(0)
@@ -430,10 +475,17 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
for (size_t i = 0; i < numVariables; ++i)
variables.append(*varStack[i].first);
codeBlock->adoptVariables(variables);
-
+ codeBlock->m_numCapturedVars = codeBlock->m_numVars;
preserveLastVar();
}
+RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
+{
+ emitOpcode(op_init_lazy_reg);
+ instructions().append(reg->index());
+ return reg;
+}
+
void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
{
// Parameters overwrite var declarations, but not function declarations.
@@ -464,7 +516,7 @@ RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
if (ident == propertyNames().arguments)
createArgumentsIfNecessary();
- return &registerFor(entry.getIndex());
+ return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
}
bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
@@ -494,6 +546,14 @@ RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
return &registerFor(entry.getIndex());
}
+RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
+{
+ if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction)
+ return reg;
+ emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index()));
+ return reg;
+}
+
RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
{
if (m_codeType == EvalCode)
@@ -503,7 +563,7 @@ RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
if (entry.isNull())
return 0;
- return &registerFor(entry.getIndex());
+ return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
}
bool BytecodeGenerator::isLocal(const Identifier& ident)
@@ -1268,6 +1328,16 @@ RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, co
return dst;
}
+RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
+{
+ emitOpcode(op_get_arguments_length);
+ instructions().append(dst->index());
+ ASSERT(base->index() == m_codeBlock->argumentsRegister());
+ instructions().append(base->index());
+ instructions().append(addConstant(propertyNames().length));
+ return dst;
+}
+
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
{
#if ENABLE(JIT)
@@ -1335,6 +1405,16 @@ RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base,
return dst;
}
+RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
+{
+ emitOpcode(op_get_argument_by_val);
+ instructions().append(dst->index());
+ ASSERT(base->index() == m_codeBlock->argumentsRegister());
+ instructions().append(base->index());
+ instructions().append(property->index());
+ return dst;
+}
+
RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
{
for (size_t i = m_forInContextStack.size(); i > 0; i--) {
@@ -1411,11 +1491,23 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen
RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
{
- unsigned index = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
+ return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false);
+}
+RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
+{
+ std::pair<FunctionOffsetMap::iterator, bool> ptr = m_functionOffsets.add(function, 0);
+ if (ptr.second)
+ ptr.first->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
+ return emitNewFunctionInternal(dst, ptr.first->second, true);
+}
+
+RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
+{
emitOpcode(op_new_func);
instructions().append(dst->index());
instructions().append(index);
+ instructions().append(doNullCheck);
return dst;
}
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index f7bd0bf..2afa0c4 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -307,6 +307,8 @@ namespace JSC {
RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
+ RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
+ RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp);
@@ -332,10 +334,12 @@ namespace JSC {
void emitMethodCheck();
RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
+ RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value);
RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
+ RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
@@ -441,7 +445,7 @@ namespace JSC {
typedef HashMap<StringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
-
+
RegisterID* newRegister();
// Adds a var slot and maps it to the name ident in symbolTable().
@@ -503,6 +507,8 @@ namespace JSC {
return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
}
+ RegisterID* emitInitLazyRegister(RegisterID*);
+
Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
SymbolTable& symbolTable() { return *m_symbolTable; }
@@ -512,6 +518,7 @@ namespace JSC {
RegisterID* emitThrowExpressionTooDeepException();
void createArgumentsIfNecessary();
+ RegisterID* createLazyRegisterIfNecessary(RegisterID*);
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
@@ -551,6 +558,12 @@ namespace JSC {
int m_globalVarStorageOffset;
+ int m_firstLazyFunction;
+ int m_lastLazyFunction;
+ HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int> > m_lazyFunctions;
+ typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
+ FunctionOffsetMap m_functionOffsets;
+
// Constant pool
IdentifierMap m_identifierMap;
JSValueMap m_jsValueMap;
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index f098ba6..2cc1a3f 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -290,6 +290,12 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (m_base->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())) {
+ RegisterID* property = generator.emitNode(m_subscript);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
+ }
+
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
RegisterID* property = generator.emitNode(m_subscript);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
@@ -300,6 +306,17 @@ RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, Regi
RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (m_ident == generator.propertyNames().length) {
+ if (!m_base->isResolveNode())
+ goto nonArgumentsPath;
+ ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
+ if (!generator.willResolveToArguments(resolveNode->identifier()))
+ goto nonArgumentsPath;
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments());
+ }
+
+nonArgumentsPath:
RegisterID* base = generator.emitNode(m_base);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
diff --git a/JavaScriptCore/docs/make-bytecode-docs.pl b/JavaScriptCore/docs/make-bytecode-docs.pl
index 9494d1b..5a95195 100755
--- a/JavaScriptCore/docs/make-bytecode-docs.pl
+++ b/JavaScriptCore/docs/make-bytecode-docs.pl
@@ -7,6 +7,7 @@ open OUTPUT, ">" . $ARGV[1];
my @undocumented = ();
+print OUTPUT "<!-- Generated from Interpreter.cpp by make-bytecode-docs.pl. -->\n";
print OUTPUT "<style>p code \{ font-size: 14px; \}</style>\n";
while (<MACHINE>) {
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index d43eb57..5943ece 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -67,6 +67,8 @@
#include "JIT.h"
#endif
+#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_INTERPRETER) && !defined(__llvm__))
+
using namespace std;
namespace JSC {
@@ -80,6 +82,11 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
}
#if ENABLE(INTERPRETER)
+static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
+{
+ return jsString(exec, strings, count);
+}
+
NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
int dst = vPC[1].u.operand;
@@ -2473,7 +2480,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_getter_proto);
#endif
DEFINE_OPCODE(op_get_by_id_getter_proto) {
@@ -2515,10 +2522,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_getter_proto:
#endif
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_custom_proto);
#endif
DEFINE_OPCODE(op_get_by_id_custom_proto) {
@@ -2557,7 +2564,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_custom_proto:
#endif
DEFINE_OPCODE(op_get_by_id_self_list) {
@@ -2648,7 +2655,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_getter_self);
#endif
DEFINE_OPCODE(op_get_by_id_getter_self) {
@@ -2688,10 +2695,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_getter_self:
#endif
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_custom_self);
#endif
DEFINE_OPCODE(op_get_by_id_custom_self) {
@@ -2725,7 +2732,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_custom_self:
#endif
DEFINE_OPCODE(op_get_by_id_generic) {
@@ -2748,7 +2755,7 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_get_by_id_generic);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_getter_chain);
#endif
DEFINE_OPCODE(op_get_by_id_getter_chain) {
@@ -2800,10 +2807,10 @@ skip_id_custom_self:
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_getter_chain:
#endif
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
goto *(&&skip_id_custom_chain);
#endif
DEFINE_OPCODE(op_get_by_id_custom_chain) {
@@ -2852,7 +2859,7 @@ skip_id_custom_self:
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
-#if ENABLE(COMPUTED_GOTO_INTERPRETER)
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_custom_chain:
#endif
DEFINE_OPCODE(op_get_array_length) {
@@ -3089,6 +3096,46 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_get_by_pname);
NEXT_INSTRUCTION();
}
+ DEFINE_OPCODE(op_get_arguments_length) {
+ int dst = vPC[1].u.operand;
+ int argumentsRegister = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
+ JSValue arguments = callFrame->r(argumentsRegister).jsValue();
+ if (arguments) {
+ Identifier& ident = codeBlock->identifier(property);
+ PropertySlot slot(arguments);
+ JSValue result = arguments.get(callFrame, ident, slot);
+ CHECK_FOR_EXCEPTION();
+ callFrame->r(dst) = result;
+ } else
+ callFrame->r(dst) = jsNumber(callFrame, callFrame->argumentCount());
+
+ vPC += OPCODE_LENGTH(op_get_arguments_length);
+ NEXT_INSTRUCTION();
+ }
+ DEFINE_OPCODE(op_get_argument_by_val) {
+ int dst = vPC[1].u.operand;
+ int argumentsRegister = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
+ JSValue arguments = callFrame->r(argumentsRegister).jsValue();
+ JSValue subscript = callFrame->r(property).jsValue();
+ if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) {
+ unsigned arg = subscript.asUInt32() + 1;
+ unsigned numParameters = callFrame->codeBlock()->m_numParameters;
+ if (arg < numParameters)
+ callFrame->r(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters);
+ else
+ callFrame->r(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters - callFrame->argumentCount() - 1);
+ vPC += OPCODE_LENGTH(op_get_argument_by_val);
+ NEXT_INSTRUCTION();
+ }
+ if (!arguments) {
+ Arguments* arguments = new (globalData) Arguments(callFrame);
+ callFrame->r(dst) = JSValue(arguments);
+ callFrame->r(unmodifiedArgumentsRegister(dst)) = JSValue(arguments);
+ }
+ // fallthrough
+ }
DEFINE_OPCODE(op_get_by_val) {
/* get_by_val dst(r) base(r) property(r)
@@ -3610,8 +3657,10 @@ skip_id_custom_self:
*/
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
+ int shouldCheck = vPC[3].u.operand;
- callFrame->r(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
+ if (!shouldCheck || !callFrame->r(dst).jsValue())
+ callFrame->r(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
vPC += OPCODE_LENGTH(op_new_func);
NEXT_INSTRUCTION();
@@ -3832,10 +3881,8 @@ skip_id_custom_self:
CHECK_FOR_EXCEPTION();
}
} else {
- if (!arguments.isObject()) {
- exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - codeBlock->instructions().begin(), codeBlock);
- goto vm_throw;
- }
+ exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - codeBlock->instructions().begin(), codeBlock);
+ goto vm_throw;
}
}
CHECK_FOR_EXCEPTION();
@@ -4137,18 +4184,17 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_convert_this);
NEXT_INSTRUCTION();
}
- DEFINE_OPCODE(op_init_arguments) {
- /* create_arguments dst(r)
+ DEFINE_OPCODE(op_init_lazy_reg) {
+ /* init_lazy_reg dst(r)
- Initialises 'arguments' to JSValue().
+ Initialises dst(r) to JSValue().
This opcode appears only at the beginning of a code block.
*/
int dst = vPC[1].u.operand;
callFrame->r(dst) = JSValue();
- callFrame->r(unmodifiedArgumentsRegister(dst)) = JSValue();
- vPC += OPCODE_LENGTH(op_init_arguments);
+ vPC += OPCODE_LENGTH(op_init_lazy_reg);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_create_arguments) {
@@ -4248,11 +4294,19 @@ skip_id_custom_self:
goto vm_throw;
}
DEFINE_OPCODE(op_strcat) {
+ /* strcat dst(r) src(r) count(n)
+
+ Construct a new String instance using the original
+ constructor, and puts the result in register dst.
+ The string will be the result of concatenating count
+ strings with values taken from registers starting at
+ register src.
+ */
int dst = vPC[1].u.operand;
int src = vPC[2].u.operand;
int count = vPC[3].u.operand;
- callFrame->r(dst) = jsString(callFrame, &callFrame->registers()[src], count);
+ callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
CHECK_FOR_EXCEPTION();
vPC += OPCODE_LENGTH(op_strcat);
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index 4466fbd..a508d0c 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -225,7 +225,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_get_callee)
DEFINE_OP(op_create_this)
DEFINE_OP(op_convert_this)
- DEFINE_OP(op_init_arguments)
+ DEFINE_OP(op_init_lazy_reg)
DEFINE_OP(op_create_arguments)
DEFINE_OP(op_debug)
DEFINE_OP(op_del_by_id)
@@ -238,7 +238,9 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
DEFINE_OP(op_get_by_id)
+ DEFINE_OP(op_get_arguments_length)
DEFINE_OP(op_get_by_val)
+ DEFINE_OP(op_get_argument_by_val)
DEFINE_OP(op_get_by_pname)
DEFINE_OP(op_get_global_var)
DEFINE_OP(op_get_pnames)
@@ -399,7 +401,9 @@ void JIT::privateCompileSlowCases()
#endif
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_get_by_id)
+ DEFINE_SLOWCASE_OP(op_get_arguments_length)
DEFINE_SLOWCASE_OP(op_get_by_val)
+ DEFINE_SLOWCASE_OP(op_get_argument_by_val)
DEFINE_SLOWCASE_OP(op_get_by_pname)
DEFINE_SLOWCASE_OP(op_instanceof)
DEFINE_SLOWCASE_OP(op_jfalse)
@@ -408,6 +412,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_jlesseq)
DEFINE_SLOWCASE_OP(op_jnlesseq)
DEFINE_SLOWCASE_OP(op_jtrue)
+ DEFINE_SLOWCASE_OP(op_load_varargs)
DEFINE_SLOWCASE_OP(op_loop_if_less)
DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
DEFINE_SLOWCASE_OP(op_loop_if_true)
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 6f1168b..6b2e70e 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -748,11 +748,13 @@ namespace JSC {
void emit_op_eq(Instruction*);
void emit_op_eq_null(Instruction*);
void emit_op_get_by_id(Instruction*);
+ void emit_op_get_arguments_length(Instruction*);
void emit_op_get_by_val(Instruction*);
+ void emit_op_get_argument_by_val(Instruction*);
void emit_op_get_by_pname(Instruction*);
void emit_op_get_global_var(Instruction*);
void emit_op_get_scoped_var(Instruction*);
- void emit_op_init_arguments(Instruction*);
+ void emit_op_init_lazy_reg(Instruction*);
void emit_op_instanceof(Instruction*);
void emit_op_jeq_null(Instruction*);
void emit_op_jfalse(Instruction*);
@@ -846,7 +848,9 @@ namespace JSC {
void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -855,6 +859,7 @@ namespace JSC {
void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false);
void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_load_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/JavaScriptCore/jit/JITCall32_64.cpp b/JavaScriptCore/jit/JITCall32_64.cpp
index aa8e987..e4005ae 100644
--- a/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/JavaScriptCore/jit/JITCall32_64.cpp
@@ -180,18 +180,6 @@ void JIT::emit_op_call_eval(Instruction* currentInstruction)
compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
}
-void JIT::emit_op_load_varargs(Instruction* currentInstruction)
-{
- int argCountDst = currentInstruction[1].u.operand;
- int argsOffset = currentInstruction[2].u.operand;
-
- JITStubCall stubCall(this, cti_op_load_varargs);
- stubCall.addArgument(Imm32(argsOffset));
- stubCall.call();
- // Stores a naked int32 in the register file.
- store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
-}
-
void JIT::emit_op_call_varargs(Instruction* currentInstruction)
{
compileOpCallVarargs(currentInstruction);
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index 2bfba83..c81932a 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -28,6 +28,7 @@
#if ENABLE(JIT)
#include "JIT.h"
+#include "Arguments.h"
#include "JITInlineMethods.h"
#include "JITStubCall.h"
#include "JSArray.h"
@@ -396,6 +397,10 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, baseVal);
emitJumpSlowCaseIfNotJSCell(regT1, proto);
+ // Check that prototype is an object
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
// Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
@@ -421,13 +426,6 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitPutVirtualRegister(dst);
}
-void JIT::emit_op_new_func(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_call(Instruction* currentInstruction)
{
compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
@@ -438,18 +436,6 @@ void JIT::emit_op_call_eval(Instruction* currentInstruction)
compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
}
-void JIT::emit_op_load_varargs(Instruction* currentInstruction)
-{
- int argCountDst = currentInstruction[1].u.operand;
- int argsOffset = currentInstruction[2].u.operand;
-
- JITStubCall stubCall(this, cti_op_load_varargs);
- stubCall.addArgument(Imm32(argsOffset));
- stubCall.call();
- // Stores a naked int32 in the register file.
- store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
-}
-
void JIT::emit_op_call_varargs(Instruction* currentInstruction)
{
compileOpCallVarargs(currentInstruction);
@@ -1225,12 +1211,11 @@ void JIT::emit_op_create_arguments(Instruction* currentInstruction)
argsCreated.link(this);
}
-void JIT::emit_op_init_arguments(Instruction* currentInstruction)
+void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * dst));
- storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * (unmodifiedArgumentsRegister(dst))));
}
void JIT::emit_op_convert_this(Instruction* currentInstruction)
@@ -1447,6 +1432,7 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value, regT2);
stubCall.addArgument(baseVal, regT2);
@@ -1484,6 +1470,88 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ sub32(Imm32(1), regT0);
+ emitFastArithReTagImmediate(regT0, regT0);
+ emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+ emitGetVirtualRegister(base, regT0);
+ JITStubCall stubCall(this, cti_op_get_by_id_generic);
+ stubCall.addArgument(regT0);
+ stubCall.addArgument(ImmPtr(ident));
+ stubCall.call(dst);
+}
+
+void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ int property = currentInstruction[3].u.operand;
+ addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
+ emitGetVirtualRegister(property, regT1);
+ addSlowCase(emitJumpIfNotImmediateInteger(regT1));
+ add32(Imm32(1), regT1);
+ // regT1 now contains the integer index of the argument we want, including this
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, regT2));
+
+ Jump skipOutofLineParams;
+ int numArgs = m_codeBlock->m_numParameters;
+ if (numArgs) {
+ Jump notInInPlaceArgs = branch32(AboveOrEqual, regT1, Imm32(numArgs));
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT0);
+ loadPtr(BaseIndex(regT0, regT1, TimesEight, 0), regT0);
+ skipOutofLineParams = jump();
+ notInInPlaceArgs.link(this);
+ }
+
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT0);
+ mul32(Imm32(sizeof(Register)), regT2, regT2);
+ subPtr(regT2, regT0);
+ loadPtr(BaseIndex(regT0, regT1, TimesEight, 0), regT0);
+ if (numArgs)
+ skipOutofLineParams.link(this);
+ emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCase(iter);
+ Jump skipArgumentsCreation = jump();
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ if (m_codeBlock->m_numParameters == 1)
+ JITStubCall(this, cti_op_create_arguments_no_params).call();
+ else
+ JITStubCall(this, cti_op_create_arguments).call();
+ emitPutVirtualRegister(arguments);
+ emitPutVirtualRegister(unmodifiedArgumentsRegister(arguments));
+
+ skipArgumentsCreation.link(this);
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(arguments, regT2);
+ stubCall.addArgument(property, regT2);
+ stubCall.call(dst);
+}
+
#endif // !USE(JSVALUE32_64)
void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction)
@@ -1528,6 +1596,88 @@ void JIT::emit_op_new_regexp(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emit_op_load_varargs(Instruction* currentInstruction)
+{
+ int argCountDst = currentInstruction[1].u.operand;
+ int argsOffset = currentInstruction[2].u.operand;
+ int expectedParams = m_codeBlock->m_numParameters - 1;
+ // Don't do inline copying if we aren't guaranteed to have a single stream
+ // of arguments
+ if (expectedParams) {
+ JITStubCall stubCall(this, cti_op_load_varargs);
+ stubCall.addArgument(Imm32(argsOffset));
+ stubCall.call();
+ // Stores a naked int32 in the register file.
+ store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
+ return;
+ }
+
+#if USE(JSVALUE32_64)
+ addSlowCase(branch32(NotEqual, tagFor(argsOffset), Imm32(JSValue::EmptyValueTag)));
+#else
+ addSlowCase(branchTestPtr(NonZero, addressFor(argsOffset)));
+#endif
+ // Load arg count into regT0
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ storePtr(regT0, addressFor(argCountDst));
+ Jump endBranch = branch32(Equal, regT0, Imm32(1));
+
+ mul32(Imm32(sizeof(Register)), regT0, regT3);
+ addPtr(Imm32(static_cast<unsigned>(sizeof(Register) - RegisterFile::CallFrameHeaderSize * sizeof(Register))), callFrameRegister, regT1);
+ subPtr(regT3, regT1); // regT1 is now the start of the out of line arguments
+ addPtr(Imm32(argsOffset * sizeof(Register)), callFrameRegister, regT2); // regT2 is the target buffer
+
+ // Bounds check the registerfile
+ addPtr(regT2, regT3);
+ addSlowCase(branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT3));
+
+ sub32(Imm32(1), regT0);
+ Label loopStart = label();
+ loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(0 - 2 * sizeof(Register))), regT3);
+ storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(0 - sizeof(Register))));
+#if USE(JSVALUE32_64)
+ loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - 2 * sizeof(Register))), regT3);
+ storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - sizeof(Register))));
+#endif
+ branchSubPtr(NonZero, Imm32(1), regT0).linkTo(loopStart, this);
+ endBranch.link(this);
+}
+
+void JIT::emitSlow_op_load_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ int argCountDst = currentInstruction[1].u.operand;
+ int argsOffset = currentInstruction[2].u.operand;
+ int expectedParams = m_codeBlock->m_numParameters - 1;
+ if (expectedParams)
+ return;
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_load_varargs);
+ stubCall.addArgument(Imm32(argsOffset));
+ stubCall.call();
+ // Stores a naked int32 in the register file.
+ store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
+}
+
+void JIT::emit_op_new_func(Instruction* currentInstruction)
+{
+ Jump lazyJump;
+ int dst = currentInstruction[1].u.operand;
+ if (currentInstruction[3].u.operand) {
+#if USE(JSVALUE32_64)
+ lazyJump = branch32(NotEqual, tagFor(dst), Imm32(JSValue::EmptyValueTag));
+#else
+ lazyJump = branchTestPtr(NonZero, addressFor(dst));
+#endif
+ }
+ JITStubCall stubCall(this, cti_op_new_func);
+ stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+ if (currentInstruction[3].u.operand)
+ lazyJump.link(this);
+}
+
// For both JSValue32_64 and JSValue32
#if ENABLE(JIT_USE_SOFT_MODULO)
#if CPU(ARM_TRADITIONAL)
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 1ad19b7..ad3b558 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -525,7 +525,11 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(value);
emitJumpSlowCaseIfNotJSCell(baseVal);
emitJumpSlowCaseIfNotJSCell(proto);
-
+
+ // Check that prototype is an object
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
// Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
@@ -562,6 +566,7 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value);
@@ -570,13 +575,6 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
stubCall.call(dst);
}
-void JIT::emit_op_new_func(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_get_global_var(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
@@ -1493,12 +1491,11 @@ void JIT::emit_op_create_arguments(Instruction* currentInstruction)
argsCreated.link(this);
}
-void JIT::emit_op_init_arguments(Instruction* currentInstruction)
+void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
emitStore(dst, JSValue());
- emitStore(unmodifiedArgumentsRegister(dst), JSValue());
}
void JIT::emit_op_get_callee(Instruction* currentInstruction)
@@ -1565,6 +1562,89 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
noProfiler.link(this);
}
+void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ sub32(Imm32(1), regT0);
+ emitStoreInt32(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int ident = currentInstruction[3].u.operand;
+
+ JITStubCall stubCall(this, cti_op_get_by_id_generic);
+ stubCall.addArgument(base);
+ stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.call(dst);
+}
+
+void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ int property = currentInstruction[3].u.operand;
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ emitLoad(property, regT1, regT2);
+ addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ add32(Imm32(1), regT2);
+ // regT2 now contains the integer index of the argument we want, including this
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT3);
+ addSlowCase(branch32(AboveOrEqual, regT2, regT3));
+
+ Jump skipOutofLineParams;
+ int numArgs = m_codeBlock->m_numParameters;
+ if (numArgs) {
+ Jump notInInPlaceArgs = branch32(AboveOrEqual, regT2, Imm32(numArgs));
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT1);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ skipOutofLineParams = jump();
+ notInInPlaceArgs.link(this);
+ }
+
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT1);
+ mul32(Imm32(sizeof(Register)), regT3, regT3);
+ subPtr(regT3, regT1);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ if (numArgs)
+ skipOutofLineParams.link(this);
+ emitStore(dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCase(iter);
+ Jump skipArgumentsCreation = jump();
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ if (m_codeBlock->m_numParameters == 1)
+ JITStubCall(this, cti_op_create_arguments_no_params).call();
+ else
+ JITStubCall(this, cti_op_create_arguments).call();
+
+ emitStore(arguments, regT1, regT0);
+ emitStore(unmodifiedArgumentsRegister(arguments), regT1, regT0);
+
+ skipArgumentsCreation.link(this);
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(arguments);
+ stubCall.addArgument(property);
+ stubCall.call(dst);
+}
+
} // namespace JSC
#endif // USE(JSVALUE32_64)
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index d5e55b4..f1ec079 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -234,15 +235,15 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif COMPILER(GCC) && CPU(ARM_THUMB2)
-#define THUNK_RETURN_ADDRESS_OFFSET 0x40
-#define PRESERVED_RETURN_ADDRESS_OFFSET 0x44
-#define PRESERVED_R4_OFFSET 0x48
-#define PRESERVED_R5_OFFSET 0x4C
-#define PRESERVED_R6_OFFSET 0x50
-#define REGISTER_FILE_OFFSET 0x54
-#define CALLFRAME_OFFSET 0x58
-#define EXCEPTION_OFFSET 0x5C
-#define ENABLE_PROFILER_REFERENCE_OFFSET 0x64
+#define THUNK_RETURN_ADDRESS_OFFSET 0x38
+#define PRESERVED_RETURN_ADDRESS_OFFSET 0x3C
+#define PRESERVED_R4_OFFSET 0x40
+#define PRESERVED_R5_OFFSET 0x44
+#define PRESERVED_R6_OFFSET 0x48
+#define REGISTER_FILE_OFFSET 0x4C
+#define CALLFRAME_OFFSET 0x50
+#define EXCEPTION_OFFSET 0x54
+#define ENABLE_PROFILER_REFERENCE_OFFSET 0x58
#elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL)
@@ -467,14 +468,14 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif COMPILER(GCC) && CPU(ARM_THUMB2)
-#define THUNK_RETURN_ADDRESS_OFFSET 0x1C
-#define PRESERVED_RETURN_ADDRESS_OFFSET 0x20
-#define PRESERVED_R4_OFFSET 0x24
-#define PRESERVED_R5_OFFSET 0x28
-#define PRESERVED_R6_OFFSET 0x2C
-#define REGISTER_FILE_OFFSET 0x30
-#define CALLFRAME_OFFSET 0x34
-#define EXCEPTION_OFFSET 0x38
+#define THUNK_RETURN_ADDRESS_OFFSET 0x20
+#define PRESERVED_RETURN_ADDRESS_OFFSET 0x24
+#define PRESERVED_R4_OFFSET 0x28
+#define PRESERVED_R5_OFFSET 0x2C
+#define PRESERVED_R6_OFFSET 0x30
+#define REGISTER_FILE_OFFSET 0x34
+#define CALLFRAME_OFFSET 0x38
+#define EXCEPTION_OFFSET 0x3C
#define ENABLE_PROFILER_REFERENCE_OFFSET 0x40
#elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index d3d7c53..2b22e6d 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -146,8 +147,8 @@ namespace JSC {
struct JITStackFrame {
JITStubArg reserved; // Unused
JITStubArg args[6];
-#if USE(JSVALUE32_64)
- void* padding[2]; // Maintain 16-byte stack alignment.
+#if !USE(JSVALUE32_64)
+ void* padding; // Maintain 16-byte stack alignment.
#endif
ReturnAddressPtr thunkReturnAddress;
@@ -162,8 +163,6 @@ namespace JSC {
CallFrame* callFrame;
JSValue* exception;
- void* padding2;
-
// These arguments passed on the stack.
Profiler** enabledProfilerReference;
JSGlobalData* globalData;
diff --git a/JavaScriptCore/jsc.pro b/JavaScriptCore/jsc.pro
index 6f3831e..670ca61 100644
--- a/JavaScriptCore/jsc.pro
+++ b/JavaScriptCore/jsc.pro
@@ -32,6 +32,10 @@ mac {
LIBS_PRIVATE += -framework AppKit
}
+wince* {
+ LIBS += mmtimer.lib
+}
+
# Prevent warnings about difference in visibility on Mac OS X
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions
diff --git a/JavaScriptCore/os-win32/inttypes.h b/JavaScriptCore/os-win32/inttypes.h
new file mode 100644
index 0000000..0ed6718
--- /dev/null
+++ b/JavaScriptCore/os-win32/inttypes.h
@@ -0,0 +1,261 @@
+// ISO C9x compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006 Alexander Chemeris
+//
+// 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.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR 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 INTTYPES_WIN32_H
+#define INTTYPES_WIN32_H
+
+#include <wtf/Platform.h>
+
+#if !COMPILER(MSVC)
+#error "This inttypes.h file should only be compiled with MSVC"
+#endif
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif
+
+#endif
+
+#endif
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp
index 540dc3b..0e526ac 100644
--- a/JavaScriptCore/parser/JSParser.cpp
+++ b/JavaScriptCore/parser/JSParser.cpp
@@ -204,6 +204,7 @@ private:
Scope()
: m_usesEval(false)
, m_needsFullActivation(false)
+ , m_allowsNewDecls(true)
{
}
@@ -212,6 +213,9 @@ private:
m_declaredVariables.add(ident->ustring().impl());
}
+ void preventNewDecls() { m_allowsNewDecls = false; }
+ bool allowsNewDecls() const { return m_allowsNewDecls; }
+
void useVariable(const Identifier* ident, bool isEval)
{
m_usesEval |= isEval;
@@ -249,6 +253,7 @@ private:
private:
bool m_usesEval;
bool m_needsFullActivation;
+ bool m_allowsNewDecls;
IdentifierSet m_declaredVariables;
IdentifierSet m_usedVariables;
IdentifierSet m_closedVariables;
@@ -287,6 +292,17 @@ private:
m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
m_scopeStack.removeLast();
}
+
+ void declareVariable(const Identifier* ident)
+ {
+ unsigned i = m_scopeStack.size() - 1;
+ ASSERT(i < m_scopeStack.size());
+ while (!m_scopeStack[i].allowsNewDecls()) {
+ i--;
+ ASSERT(i < m_scopeStack.size());
+ }
+ m_scopeStack[i].declareVariable(ident);
+ }
ScopeStack m_scopeStack;
};
@@ -425,7 +441,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr
lastIdent = name;
next();
bool hasInitializer = match(EQUAL);
- currentScope()->declareVariable(name);
+ declareVariable(name);
context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
if (hasInitializer) {
int varDivot = tokenStart() + 1;
@@ -457,7 +473,7 @@ template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationLi
const Identifier* name = m_token.m_data.ident;
next();
bool hasInitializer = match(EQUAL);
- currentScope()->declareVariable(name);
+ declareVariable(name);
context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
TreeExpression initializer = 0;
if (hasInitializer) {
@@ -759,6 +775,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild
next();
ScopeRef catchScope = pushScope();
catchScope->declareVariable(ident);
+ catchScope->preventNewDecls();
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
int initialEvalCount = context.evalCount();
@@ -862,7 +879,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);
+ declareVariable(m_token.m_data.ident);
TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
TreeFormalParameterList tail = list;
next();
@@ -870,7 +887,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
next();
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
- currentScope()->declareVariable(ident);
+ declareVariable(ident);
next();
usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident;
tail = context.createFormalParameterList(tail, *ident);
@@ -933,7 +950,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseFunctionDeclaration(Tr
int bodyStartLine = 0;
failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
failIfFalse(name);
- currentScope()->declareVariable(name);
+ declareVariable(name);
return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index 2d8448c..fa61cdc 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -1412,8 +1412,11 @@ namespace JSC {
bool usesArguments() const { return m_features & ArgumentsFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
+ bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog
index e80493b..11018b4 100644
--- a/JavaScriptCore/qt/ChangeLog
+++ b/JavaScriptCore/qt/ChangeLog
@@ -1,3 +1,39 @@
+2010-09-29 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] QScriptEngine should have an API for creating Date objects
+ https://bugs.webkit.org/show_bug.cgi?id=41667
+
+ Implement newDate(), isDate() and toDateTime() functions. Use the
+ QDateTime::{to,set}MSecsSinceEpoch() functions to do the
+ calculations.
+
+ * api/qscriptengine.cpp:
+ (QScriptEngine::newDate):
+ * api/qscriptengine.h:
+ * api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::newDate):
+ * api/qscriptengine_p.h:
+ (QScriptEnginePrivate::isDate):
+
+ * api/qscriptoriginalglobalobject_p.h:
+ (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): need
+ to keep track of Date Constructor and Prototype.
+ (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): ditto.
+ (QScriptOriginalGlobalObject::isDate): use the Date Constructor
+ and Prototype to identify Date values.
+
+ * api/qscriptvalue.cpp:
+ (QScriptValue::isDate):
+ (QScriptValue::toDateTime):
+ * api/qscriptvalue.h:
+ * api/qscriptvalue_p.h:
+ (QScriptValuePrivate::isDate):
+ (QScriptValuePrivate::toDateTime):
+ * tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::newDate):
+
2010-07-27 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
index 7ef7c8e..607b0b9 100644
--- a/JavaScriptCore/qt/api/qscriptengine.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -25,6 +25,8 @@
#include "qscriptprogram_p.h"
#include "qscriptsyntaxcheckresult_p.h"
#include "qscriptvalue_p.h"
+#include <QtCore/qdatetime.h>
+#include <QtCore/qnumeric.h>
/*!
Constructs a QScriptEngine object.
@@ -368,6 +370,27 @@ QScriptValue QScriptEngine::newArray(uint length)
}
/*!
+ Creates a QtScript object of class Date with the given \a value
+ (the number of milliseconds since 01 January 1970, UTC).
+*/
+QScriptValue QScriptEngine::newDate(qsreal value)
+{
+ return QScriptValuePrivate::get(d_ptr->newDate(value));
+}
+
+/*!
+ Creates a QtScript object of class Date from the given \a value.
+
+ \sa QScriptValue::toDateTime()
+*/
+QScriptValue QScriptEngine::newDate(const QDateTime& value)
+{
+ if (value.isValid())
+ return QScriptValuePrivate::get(d_ptr->newDate(qsreal(value.toMSecsSinceEpoch())));
+ return QScriptValuePrivate::get(d_ptr->newDate(qSNaN()));
+}
+
+/*!
Returns this engine's Global Object.
By default, the Global Object contains the built-in objects that are
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
index b85dc52..281707f 100644
--- a/JavaScriptCore/qt/api/qscriptengine.h
+++ b/JavaScriptCore/qt/api/qscriptengine.h
@@ -23,11 +23,12 @@
#include "qscriptprogram.h"
#include "qscriptstring.h"
#include "qscriptsyntaxcheckresult.h"
+#include "qscriptvalue.h"
#include <QtCore/qobject.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
-class QScriptValue;
+class QDateTime;
class QScriptEnginePrivate;
// FIXME: Remove this once QScriptContext is properly defined.
@@ -69,6 +70,8 @@ public:
QScriptValue newObject();
QScriptValue newArray(uint length = 0);
+ QScriptValue newDate(qsreal value);
+ QScriptValue newDate(const QDateTime& value);
QScriptValue globalObject() const;
private:
friend class QScriptEnginePrivate;
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index a708a34..89054c0 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -146,6 +146,20 @@ QScriptValuePrivate* QScriptEnginePrivate::newArray(uint length)
return new QScriptValuePrivate(this, array);
}
+QScriptValuePrivate* QScriptEnginePrivate::newDate(qsreal value)
+{
+ JSValueRef exception = 0;
+ JSValueRef argument = JSValueMakeNumber(m_context, value);
+ JSObjectRef result = JSObjectMakeDate(m_context, /* argumentCount */ 1, &argument, &exception);
+
+ if (exception) {
+ setException(exception, NotNullException);
+ return new QScriptValuePrivate();
+ }
+
+ return new QScriptValuePrivate(this, result);
+}
+
QScriptValuePrivate* QScriptEnginePrivate::globalObject() const
{
JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
index eec1929..4603b91 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.h
+++ b/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -77,16 +77,19 @@ public:
QScriptValuePrivate* newObject() const;
QScriptValuePrivate* newArray(uint length);
+ QScriptValuePrivate* newDate(qsreal value);
QScriptValuePrivate* globalObject() const;
inline QScriptStringPrivate* toStringHandle(const QString& str) const;
inline operator JSGlobalContextRef() const;
+ inline bool isDate(JSValueRef value) const;
inline bool isArray(JSValueRef value) const;
inline bool isError(JSValueRef value) const;
inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
+
private:
QScriptEngine* q_ptr;
JSGlobalContextRef m_context;
@@ -226,6 +229,11 @@ QScriptEnginePrivate::operator JSGlobalContextRef() const
return m_context;
}
+bool QScriptEnginePrivate::isDate(JSValueRef value) const
+{
+ return m_originalGlobalObject.isDate(value);
+}
+
bool QScriptEnginePrivate::isArray(JSValueRef value) const
{
return m_originalGlobalObject.isArray(value);
diff --git a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
index 31e94f7..2bd945f 100644
--- a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
+++ b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
@@ -43,6 +43,7 @@ public:
inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
+ inline bool isDate(JSValueRef value) const;
inline bool isArray(JSValueRef value) const;
inline bool isError(JSValueRef value) const;
@@ -61,6 +62,8 @@ private:
JSValueRef m_errorPrototype;
JSObjectRef m_functionConstructor;
JSValueRef m_functionPrototype;
+ JSObjectRef m_dateConstructor;
+ JSValueRef m_datePrototype;
// Reference to standard JS functions that are not exposed by JSC C API.
JSObjectRef m_hasOwnPropertyFunction;
@@ -78,6 +81,7 @@ QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef cont
initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype);
initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype);
initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype);
+ initializeMember(globalObject, propertyName.get(), "Date", m_dateConstructor, m_datePrototype);
propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty"));
m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
@@ -126,6 +130,8 @@ QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject()
JSValueUnprotect(m_context, m_errorPrototype);
JSValueUnprotect(m_context, m_functionConstructor);
JSValueUnprotect(m_context, m_functionPrototype);
+ JSValueUnprotect(m_context, m_dateConstructor);
+ JSValueUnprotect(m_context, m_datePrototype);
JSValueUnprotect(m_context, m_hasOwnPropertyFunction);
JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction);
JSGlobalContextRelease(m_context);
@@ -170,6 +176,11 @@ inline QVector<JSStringRef> QScriptOriginalGlobalObject::objectGetOwnPropertyNam
return names;
}
+inline bool QScriptOriginalGlobalObject::isDate(JSValueRef value) const
+{
+ return isType(value, m_dateConstructor, m_datePrototype);
+}
+
inline bool QScriptOriginalGlobalObject::isArray(JSValueRef value) const
{
return isType(value, m_arrayConstructor, m_arrayPrototype);
diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp
index a7d0b7b..8a7a6c4 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.cpp
+++ b/JavaScriptCore/qt/api/qscriptvalue.cpp
@@ -324,6 +324,17 @@ bool QScriptValue::isArray() const
}
/*!
+ Returns true if this QScriptValue is an object of the Date class;
+ otherwise returns false.
+
+ \sa QScriptEngine::newDate()
+*/
+bool QScriptValue::isDate() const
+{
+ return d_ptr->isDate();
+}
+
+/*!
Returns true if this QScriptValue is of the Object type; otherwise
returns false.
@@ -488,6 +499,18 @@ QScriptValue QScriptValue::toObject() const
}
/*!
+ Returns a QDateTime representation of this value, in local time.
+ If this QScriptValue is not a date, or the value of the date is
+ NaN (Not-a-Number), an invalid QDateTime is returned.
+
+ \sa isDate()
+*/
+QDateTime QScriptValue::toDateTime() const
+{
+ return d_ptr->toDateTime();
+}
+
+/*!
Calls this QScriptValue as a function, using \a thisObject as
the `this' object in the function call, and passing \a args
as arguments to the function. Returns the value returned from
diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h
index 991a6a0..bd33849 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.h
+++ b/JavaScriptCore/qt/api/qscriptvalue.h
@@ -26,6 +26,7 @@
class QScriptEngine;
class QScriptValuePrivate;
+class QDateTime;
class QScriptValue;
typedef QList<QScriptValue> QScriptValueList;
@@ -112,6 +113,7 @@ public:
bool isObject() const;
bool isError() const;
bool isArray() const;
+ bool isDate() const;
QString toString() const;
qsreal toNumber() const;
@@ -122,6 +124,7 @@ public:
quint32 toUInt32() const;
quint16 toUInt16() const;
QScriptValue toObject() const;
+ QDateTime toDateTime() const;
QScriptValue call(const QScriptValue& thisObject = QScriptValue(),
const QScriptValueList& args = QScriptValueList());
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 6fbf98b..f98a06a 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -26,6 +26,7 @@
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <JSObjectRefPrivate.h>
+#include <QtCore/qdatetime.h>
#include <QtCore/qmath.h>
#include <QtCore/qnumeric.h>
#include <QtCore/qshareddata.h>
@@ -102,6 +103,7 @@ public:
inline bool isObject();
inline bool isFunction();
inline bool isArray();
+ inline bool isDate();
inline QString toString() const;
inline qsreal toNumber() const;
@@ -113,6 +115,7 @@ public:
inline QScriptValuePrivate* toObject(QScriptEnginePrivate* engine);
inline QScriptValuePrivate* toObject();
+ inline QDateTime toDateTime();
inline QScriptValuePrivate* prototype();
inline void setPrototype(QScriptValuePrivate* prototype);
@@ -462,6 +465,20 @@ bool QScriptValuePrivate::isArray()
}
}
+bool QScriptValuePrivate::isDate()
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return false;
+ // Fall-through.
+ case JSObject:
+ return m_engine->isDate(*this);
+ default:
+ return false;
+ }
+}
+
QString QScriptValuePrivate::toString() const
{
switch (m_state) {
@@ -662,6 +679,24 @@ QScriptValuePrivate* QScriptValuePrivate::toObject()
return new QScriptValuePrivate;
}
+QDateTime QScriptValuePrivate::toDateTime()
+{
+ if (!isDate())
+ return QDateTime();
+
+ JSValueRef exception = 0;
+ qsreal t = JSValueToNumber(*m_engine, *this, &exception);
+
+ if (exception) {
+ m_engine->setException(exception, QScriptEnginePrivate::NotNullException);
+ return QDateTime();
+ }
+
+ QDateTime result;
+ result.setMSecsSinceEpoch(qint64(t));
+ return result;
+}
+
inline QScriptValuePrivate* QScriptValuePrivate::prototype()
{
if (isObject()) {
diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
index 58a1587..dabcfb2 100644
--- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
+++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
@@ -21,6 +21,7 @@
#include "qscriptprogram.h"
#include "qscriptsyntaxcheckresult.h"
#include "qscriptvalue.h"
+#include <QtCore/qnumeric.h>
#include <QtTest/qtest.h>
class tst_QScriptEngine : public QObject {
@@ -50,6 +51,7 @@ private slots:
void toObjectTwoEngines();
void newArray();
void uncaughtException();
+ void newDate();
};
/* Evaluating a script that throw an unhandled exception should return an invalid value. */
@@ -681,5 +683,52 @@ void tst_QScriptEngine::uncaughtException()
}
}
+void tst_QScriptEngine::newDate()
+{
+ QScriptEngine eng;
+ {
+ QScriptValue date = eng.newDate(0);
+ QCOMPARE(date.isValid(), true);
+ QCOMPARE(date.isDate(), true);
+ QCOMPARE(date.isObject(), true);
+ QVERIFY(!date.isFunction());
+ // prototype should be Date.prototype
+ QCOMPARE(date.prototype().isValid(), true);
+ QCOMPARE(date.prototype().isDate(), true);
+ QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
+ }
+ {
+ QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::LocalTime);
+ QScriptValue date = eng.newDate(dt);
+ QCOMPARE(date.isValid(), true);
+ QCOMPARE(date.isDate(), true);
+ QCOMPARE(date.isObject(), true);
+ // prototype should be Date.prototype
+ QCOMPARE(date.prototype().isValid(), true);
+ QCOMPARE(date.prototype().isDate(), true);
+ QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
+
+ QCOMPARE(date.toDateTime(), dt);
+ }
+ {
+ QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::UTC);
+ QScriptValue date = eng.newDate(dt);
+ // toDateTime() result should be in local time
+ QCOMPARE(date.toDateTime(), dt.toLocalTime());
+ }
+ // Date.parse() should return NaN when it fails
+ {
+ QScriptValue ret = eng.evaluate("Date.parse()");
+ QVERIFY(ret.isNumber());
+ QVERIFY(qIsNaN(ret.toNumber()));
+ }
+ // Date.parse() should be able to parse the output of Date().toString()
+ {
+ QScriptValue ret = eng.evaluate("var x = new Date(); var s = x.toString(); s == new Date(Date.parse(s)).toString()");
+ QVERIFY(ret.isBoolean());
+ QCOMPARE(ret.toBoolean(), true);
+ }
+}
+
QTEST_MAIN(tst_QScriptEngine)
#include "tst_qscriptengine.moc"
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
index d892de0..49c8b3b 100644
--- a/JavaScriptCore/runtime/Arguments.h
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -225,7 +225,7 @@ namespace JSC {
ASSERT(!d()->registerArray);
size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
- size_t numVars = d()->functionExecutable->variableCount();
+ size_t numVars = d()->functionExecutable->capturedVariableCount();
size_t numLocals = numVars + numParametersMinusThis;
if (!numLocals)
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 5b2f916..49e0405 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -90,25 +90,34 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
value = primitive.toNumber(exec);
}
} else {
- if (isnan(args.at(0).toNumber(exec))
- || isnan(args.at(1).toNumber(exec))
- || (numArgs >= 3 && isnan(args.at(2).toNumber(exec)))
- || (numArgs >= 4 && isnan(args.at(3).toNumber(exec)))
- || (numArgs >= 5 && isnan(args.at(4).toNumber(exec)))
- || (numArgs >= 6 && isnan(args.at(5).toNumber(exec)))
- || (numArgs >= 7 && isnan(args.at(6).toNumber(exec))))
+ double doubleArguments[7] = {
+ args.at(0).toNumber(exec),
+ args.at(1).toNumber(exec),
+ args.at(2).toNumber(exec),
+ args.at(3).toNumber(exec),
+ args.at(4).toNumber(exec),
+ args.at(5).toNumber(exec),
+ args.at(6).toNumber(exec)
+ };
+ if (isnan(doubleArguments[0])
+ || isnan(doubleArguments[1])
+ || (numArgs >= 3 && isnan(doubleArguments[2]))
+ || (numArgs >= 4 && isnan(doubleArguments[3]))
+ || (numArgs >= 5 && isnan(doubleArguments[4]))
+ || (numArgs >= 6 && isnan(doubleArguments[5]))
+ || (numArgs >= 7 && isnan(doubleArguments[6])))
value = NaN;
else {
GregorianDateTime t;
- int year = args.at(0).toInt32(exec);
+ int year = JSC::toInt32(doubleArguments[0]);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = args.at(1).toInt32(exec);
- t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1;
- t.hour = args.at(3).toInt32(exec);
- t.minute = args.at(4).toInt32(exec);
- t.second = args.at(5).toInt32(exec);
+ t.month = JSC::toInt32(doubleArguments[1]);
+ t.monthDay = (numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1;
+ t.hour = JSC::toInt32(doubleArguments[3]);
+ t.minute = JSC::toInt32(doubleArguments[4]);
+ t.second = JSC::toInt32(doubleArguments[5]);
t.isDST = -1;
- double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
+ double ms = (numArgs >= 7) ? doubleArguments[6] : 0;
value = gregorianDateTimeToMS(exec, t, ms, false);
}
}
@@ -160,25 +169,34 @@ static EncodedJSValue JSC_HOST_CALL dateNow(ExecState* exec)
static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec)
{
+ double doubleArguments[7] = {
+ exec->argument(0).toNumber(exec),
+ exec->argument(1).toNumber(exec),
+ exec->argument(2).toNumber(exec),
+ exec->argument(3).toNumber(exec),
+ exec->argument(4).toNumber(exec),
+ exec->argument(5).toNumber(exec),
+ exec->argument(6).toNumber(exec)
+ };
int n = exec->argumentCount();
- if (isnan(exec->argument(0).toNumber(exec))
- || isnan(exec->argument(1).toNumber(exec))
- || (n >= 3 && isnan(exec->argument(2).toNumber(exec)))
- || (n >= 4 && isnan(exec->argument(3).toNumber(exec)))
- || (n >= 5 && isnan(exec->argument(4).toNumber(exec)))
- || (n >= 6 && isnan(exec->argument(5).toNumber(exec)))
- || (n >= 7 && isnan(exec->argument(6).toNumber(exec))))
+ if (isnan(doubleArguments[0])
+ || isnan(doubleArguments[1])
+ || (n >= 3 && isnan(doubleArguments[2]))
+ || (n >= 4 && isnan(doubleArguments[3]))
+ || (n >= 5 && isnan(doubleArguments[4]))
+ || (n >= 6 && isnan(doubleArguments[5]))
+ || (n >= 7 && isnan(doubleArguments[6])))
return JSValue::encode(jsNaN(exec));
GregorianDateTime t;
- int year = exec->argument(0).toInt32(exec);
+ int year = JSC::toInt32(doubleArguments[0]);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = exec->argument(1).toInt32(exec);
- t.monthDay = (n >= 3) ? exec->argument(2).toInt32(exec) : 1;
- t.hour = exec->argument(3).toInt32(exec);
- t.minute = exec->argument(4).toInt32(exec);
- t.second = exec->argument(5).toInt32(exec);
- double ms = (n >= 7) ? exec->argument(6).toNumber(exec) : 0;
+ t.month = JSC::toInt32(doubleArguments[1]);
+ t.monthDay = (n >= 3) ? JSC::toInt32(doubleArguments[2]) : 1;
+ t.hour = JSC::toInt32(doubleArguments[3]);
+ t.minute = JSC::toInt32(doubleArguments[4]);
+ t.second = JSC::toInt32(doubleArguments[5]);
+ double ms = (n >= 7) ? doubleArguments[6] : 0;
return JSValue::encode(jsNumber(exec, timeClip(gregorianDateTimeToMS(exec, t, ms, true))));
}
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index e14955c..871f3e2 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -65,7 +65,7 @@ ProgramExecutable::~ProgramExecutable()
FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
: ScriptExecutable(globalData, source)
- , m_numVariables(0)
+ , m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
, m_name(name)
@@ -77,7 +77,7 @@ FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifie
FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
: ScriptExecutable(exec, source)
- , m_numVariables(0)
+ , m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
, m_name(name)
@@ -197,7 +197,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
generator->generate();
m_numParametersForCall = m_codeBlockForCall->m_numParameters;
ASSERT(m_numParametersForCall);
- m_numVariables = m_codeBlockForCall->m_numVars;
+ m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars;
m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
body->destroyData();
@@ -238,7 +238,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
generator->generate();
m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters;
ASSERT(m_numParametersForConstruct);
- m_numVariables = m_codeBlockForConstruct->m_numVars;
+ m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars;
m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
body->destroyData();
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index c168ac8..feab7ef 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -144,6 +144,7 @@ namespace JSC {
, m_features(0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
+ relaxAdoptionRequirement();
if (SamplingTool* sampler = globalData->interpreter->sampler())
sampler->notifyOfScope(this);
#else
@@ -157,6 +158,7 @@ namespace JSC {
, m_features(0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
+ relaxAdoptionRequirement();
if (SamplingTool* sampler = exec->globalData().interpreter->sampler())
sampler->notifyOfScope(this);
#else
@@ -347,7 +349,7 @@ namespace JSC {
const Identifier& name() { return m_name; }
size_t parameterCount() const { return m_parameters->size(); }
- unsigned variableCount() const { return m_numVariables; }
+ unsigned capturedVariableCount() const { return m_numCapturedVariables; }
UString paramString() const;
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
@@ -364,7 +366,7 @@ namespace JSC {
virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
- unsigned m_numVariables : 31;
+ unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
RefPtr<FunctionParameters> m_parameters;
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index 8cf71d0..d121518 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -62,12 +62,65 @@ void JSActivation::markChildren(MarkStack& markStack)
size_t count = numParametersMinusThis;
markStack.appendValues(registerArray, count);
- size_t numVars = d()->functionExecutable->variableCount();
+ size_t numVars = d()->functionExecutable->capturedVariableCount();
// Skip the call frame, which sits between the parameters and vars.
markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
}
+inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
+{
+ SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+ if (!entry.isNull()) {
+ ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
+ slot.setRegisterSlot(&registerAt(entry.getIndex()));
+ return true;
+ }
+ return false;
+}
+
+inline bool JSActivation::symbolTablePut(const Identifier& propertyName, JSValue value)
+{
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+ SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+ if (entry.isNull())
+ return false;
+ if (entry.isReadOnly())
+ return true;
+ ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
+ registerAt(entry.getIndex()) = value;
+ return true;
+}
+
+void JSActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ SymbolTable::const_iterator end = symbolTable().end();
+ for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
+ ASSERT(it->second.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
+ if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
+ propertyNames.add(Identifier(exec, it->first.get()));
+ }
+ // Skip the JSVariableObject implementation of getOwnPropertyNames
+ JSObject::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
+inline bool JSActivation::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+ SymbolTable::iterator iter = symbolTable().find(propertyName.impl());
+ if (iter == symbolTable().end())
+ return false;
+ SymbolTableEntry& entry = iter->second;
+ ASSERT(!entry.isNull());
+ if (entry.getIndex() >= static_cast<int>(d()->functionExecutable->capturedVariableCount()))
+ return false;
+ entry.setAttributes(attributes);
+ registerAt(entry.getIndex()) = value;
+ return true;
+}
+
bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().arguments) {
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index d5e7991..9ff9168 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -52,6 +52,7 @@ namespace JSC {
virtual bool isActivationObject() const { return true; }
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode);
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
@@ -87,7 +88,13 @@ namespace JSC {
RefPtr<FunctionExecutable> functionExecutable;
};
-
+
+ bool symbolTableGet(const Identifier&, PropertySlot&);
+ bool symbolTableGet(const Identifier&, PropertyDescriptor&);
+ bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
+ bool symbolTablePut(const Identifier&, JSValue);
+ bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes);
+
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 340cb75..dae807f 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -202,12 +202,20 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
: JSObject(structure)
{
unsigned initialCapacity = list.size();
-
- m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
+ unsigned initialStorage;
+
+ // If the ArgList is empty, allocate space for 3 entries. This value empirically
+ // works well for benchmarks.
+ if (!initialCapacity)
+ initialStorage = 3;
+ else
+ initialStorage = initialCapacity;
+
+ m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialStorage)));
m_storage->m_allocBase = m_storage;
m_indexBias = 0;
m_storage->m_length = initialCapacity;
- m_vectorLength = initialCapacity;
+ m_vectorLength = initialStorage;
m_storage->m_numValuesInVector = initialCapacity;
m_storage->m_sparseValueMap = 0;
m_storage->subclassData = 0;
@@ -221,10 +229,12 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
ArgList::const_iterator end = list.end();
for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
vector[i] = *it;
+ for (; i < initialStorage; i++)
+ vector[i] = JSValue();
checkConsistency();
- Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity));
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(initialStorage));
}
JSArray::~JSArray()
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index 2ffce8d..cfa1454 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -34,7 +34,24 @@
namespace JSC {
- class JSCell : public NoncopyableCustomAllocated {
+#if COMPILER(MSVC)
+ // If WTF_MAKE_NONCOPYABLE is applied to JSCell we end up with a bunch of
+ // undefined references to the JSCell copy constructor and assignment operator
+ // when linking JavaScriptCore.
+ class MSVCBugWorkaround {
+ WTF_MAKE_NONCOPYABLE(MSVCBugWorkaround);
+
+ protected:
+ MSVCBugWorkaround() { }
+ ~MSVCBugWorkaround() { }
+ };
+
+ class JSCell : MSVCBugWorkaround {
+#else
+ class JSCell {
+ WTF_MAKE_NONCOPYABLE(JSCell);
+#endif
+
friend class GetterSetter;
friend class Heap;
friend class JIT;
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
index 5648264..8d2ae2d 100644
--- a/JavaScriptCore/runtime/MathObject.cpp
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -135,7 +135,9 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec)
EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec)
{
- return JSValue::encode(jsDoubleNumber(exec, atan2(exec->argument(0).toNumber(exec), exec->argument(1).toNumber(exec))));
+ double arg0 = exec->argument(0).toNumber(exec);
+ double arg1 = exec->argument(1).toNumber(exec);
+ return JSValue::encode(jsDoubleNumber(exec, atan2(arg0, arg1)));
}
EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec)
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index d4545cb..3ebfe0f 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -115,8 +115,6 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
{
if (startOffset < 0)
startOffset = 0;
- if (ovector)
- ovector->resize(0);
#if ENABLE(REGEXP_TRACING)
m_rtMatchCallCount++;
@@ -142,7 +140,10 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
}
ASSERT(offsetVector);
- for (int j = 0; j < offsetVectorSize; ++j)
+ // Initialize offsetVector with the return value (index 0) and the
+ // first subpattern start indicies (even index values) set to -1.
+ // No need to init the subpattern end indicies.
+ for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
offsetVector[j] = -1;
#if ENABLE(YARR_JIT)
@@ -157,8 +158,6 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (result != -1)
fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
#endif
- if (ovector)
- ovector->clear();
}
#if ENABLE(REGEXP_TRACING)
@@ -255,7 +254,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (codeBlock.getFallback())
sprintf(jitAddr, "fallback");
else
- sprintf(jitAddr, "0x%014lx", (uintptr_t)codeBlock.getAddr());
+ sprintf(jitAddr, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.getAddr()));
#else
const char* jitAddr = "JIT Off";
#endif
diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp
index 273e0e0..9222c1d 100644
--- a/JavaScriptCore/wtf/Assertions.cpp
+++ b/JavaScriptCore/wtf/Assertions.cpp
@@ -42,12 +42,11 @@
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
-#include <windows.h>
#include <crtdbg.h>
#endif
-#if OS(WINCE)
-#include <winbase.h>
+#if OS(WINDOWS)
+#include <windows.h>
#endif
#if PLATFORM(BREWMP)
@@ -113,7 +112,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
printLog(buffer);
}
-#elif COMPILER(MSVC) && !defined(WINCEBASIC)
+#elif HAVE(ISDEBUGGERPRESENT)
if (IsDebuggerPresent()) {
size_t size = 1024;
diff --git a/JavaScriptCore/wtf/Noncopyable.h b/JavaScriptCore/wtf/Noncopyable.h
index 60a46e2..898c1ba 100644
--- a/JavaScriptCore/wtf/Noncopyable.h
+++ b/JavaScriptCore/wtf/Noncopyable.h
@@ -21,6 +21,26 @@
#ifndef WTF_Noncopyable_h
#define WTF_Noncopyable_h
+#ifndef __has_feature
+ #define __has_feature(x) 0
+#endif
+
+#if __has_feature(cxx_deleted_functions)
+ #define WTF_MAKE_NONCOPYABLE(ClassName) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
+ _Pragma("clang diagnostic ignored \"-Wc++0x-extensions\"") \
+ private: \
+ ClassName(const ClassName&) = delete; \
+ ClassName& operator=(const ClassName&) = delete; \
+ _Pragma("clang diagnostic pop")
+#else
+ #define WTF_MAKE_NONCOPYABLE(ClassName) \
+ private: \
+ ClassName(const ClassName&); \
+ ClassName& operator=(const ClassName&)
+#endif
+
// We don't want argument-dependent lookup to pull in everything from the WTF
// namespace when you use Noncopyable, so put it in its own namespace.
@@ -36,17 +56,8 @@ namespace WTFNoncopyable {
~Noncopyable() { }
};
- class NoncopyableCustomAllocated {
- NoncopyableCustomAllocated(const NoncopyableCustomAllocated&);
- NoncopyableCustomAllocated& operator=(const NoncopyableCustomAllocated&);
- protected:
- NoncopyableCustomAllocated() { }
- ~NoncopyableCustomAllocated() { }
- };
-
} // namespace WTFNoncopyable
using WTFNoncopyable::Noncopyable;
-using WTFNoncopyable::NoncopyableCustomAllocated;
#endif // WTF_Noncopyable_h
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h
index b43c5ba..052d6e2 100644
--- a/JavaScriptCore/wtf/PassRefPtr.h
+++ b/JavaScriptCore/wtf/PassRefPtr.h
@@ -48,13 +48,13 @@ namespace WTF {
template<typename T> REF_DEREF_INLINE void refIfNotNull(T* ptr)
{
- if (UNLIKELY(ptr != 0))
+ if (LIKELY(ptr != 0))
ptr->ref();
}
template<typename T> REF_DEREF_INLINE void derefIfNotNull(T* ptr)
{
- if (UNLIKELY(ptr != 0))
+ if (LIKELY(ptr != 0))
ptr->deref();
}
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 30bc795..1843bea 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -746,6 +746,7 @@
#else
#define HAVE_SYS_TIMEB_H 1
#define HAVE_ALIGNED_MALLOC 1
+#define HAVE_ISDEBUGGERPRESENT 1
#endif
#define HAVE_VIRTUALALLOC 1
@@ -964,7 +965,8 @@
/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */
#if !defined(ENABLE_JIT) \
&& (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \
- && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4,1,0))
+ && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4,1,0)) \
+ && !OS(WINCE)
#define ENABLE_JIT 1
#endif
@@ -1142,7 +1144,7 @@
#define ENABLE_BRANCH_COMPACTION 1
#endif
-#if PLATFORM(GTK) || (PLATFORM(EFL) && ENABLE(GLIB_SUPPORT))
+#if ENABLE(GLIB_SUPPORT)
#include "GTypedefs.h"
#endif
diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h
index d85c47e..8d8b302 100644
--- a/JavaScriptCore/wtf/RefCounted.h
+++ b/JavaScriptCore/wtf/RefCounted.h
@@ -145,7 +145,9 @@ protected:
}
};
-template<typename T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated {
+template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
+ WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
+
public:
void deref()
{
diff --git a/JavaScriptCore/wtf/StringHashFunctions.h b/JavaScriptCore/wtf/StringHashFunctions.h
index 07f117f..3ad7701 100644
--- a/JavaScriptCore/wtf/StringHashFunctions.h
+++ b/JavaScriptCore/wtf/StringHashFunctions.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,130 +28,142 @@ namespace WTF {
// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
static const unsigned stringHashingStartValue = 0x9e3779b9U;
-// stringHash methods based on Paul Hsieh's SuperFastHash.
+// Paul Hsieh's SuperFastHash
// http://www.azillionmonkeys.com/qed/hash.html
// char* data is interpreted as latin-encoded (zero extended to 16 bits).
+class StringHasher {
+public:
+ inline StringHasher()
+ : m_hash(stringHashingStartValue)
+ , m_hasPendingCharacter(false)
+ , m_pendingCharacter(0)
+ {
+ }
-inline unsigned stringHash(const UChar* data, unsigned length)
-{
- unsigned hash = WTF::stringHashingStartValue;
- unsigned rem = length & 1;
- length >>= 1;
-
- // Main loop
- for (; length > 0; length--) {
- hash += data[0];
- unsigned tmp = (data[1] << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2;
- hash += hash >> 11;
+ inline void addCharacters(UChar a, UChar b)
+ {
+ ASSERT(!m_hasPendingCharacter);
+ addCharactersToHash(a, b);
}
- // Handle end case
- if (rem) {
- hash += data[0];
- hash ^= hash << 11;
- hash += hash >> 17;
+ inline void addCharacter(UChar ch)
+ {
+ if (m_hasPendingCharacter) {
+ addCharactersToHash(m_pendingCharacter, ch);
+ m_hasPendingCharacter = false;
+ return;
+ }
+
+ m_pendingCharacter = ch;
+ m_hasPendingCharacter = true;
}
- // Force "avalanching" of final 127 bits
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- hash &= 0x7fffffff;
-
- // this avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked
- if (hash == 0)
- hash = 0x40000000;
-
- return hash;
-}
-
-inline unsigned stringHash(const char* data, unsigned length)
-{
- unsigned hash = WTF::stringHashingStartValue;
- unsigned rem = length & 1;
- length >>= 1;
-
- // Main loop
- for (; length > 0; length--) {
- hash += static_cast<unsigned char>(data[0]);
- unsigned tmp = (static_cast<unsigned char>(data[1]) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2;
- hash += hash >> 11;
+ inline unsigned hash() const
+ {
+ unsigned result = m_hash;
+
+ // Handle end case.
+ if (m_hasPendingCharacter) {
+ result += m_pendingCharacter;
+ result ^= result << 11;
+ result += result >> 17;
+ }
+
+ // Force "avalanching" of final 31 bits.
+ result ^= result << 3;
+ result += result >> 5;
+ result ^= result << 2;
+ result += result >> 15;
+ result ^= result << 10;
+
+ // First bit is used in UStringImpl for m_isIdentifier.
+ result &= 0x7fffffff;
+
+ // This avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked.
+ if (!result)
+ return 0x40000000;
+
+ return result;
}
- // Handle end case
- if (rem) {
- hash += static_cast<unsigned char>(data[0]);
- hash ^= hash << 11;
- hash += hash >> 17;
+ template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data, unsigned length)
+ {
+ StringHasher hasher;
+ bool rem = length & 1;
+ length >>= 1;
+
+ while (length--) {
+ hasher.addCharacters(Converter(data[0]), Converter(data[1]));
+ data += 2;
+ }
+
+ if (rem)
+ hasher.addCharacter(Converter(*data));
+
+ return hasher.hash();
}
- // Force "avalanching" of final 127 bits
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- hash &= 0x7fffffff;
-
- // this avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked
- if (hash == 0)
- hash = 0x40000000;
-
- return hash;
-}
-
-inline unsigned stringHash(const char* data)
-{
- unsigned hash = WTF::stringHashingStartValue;
-
- // Main loop
- for (;;) {
- unsigned char b0 = data[0];
- if (!b0)
- break;
- unsigned char b1 = data[1];
- if (!b1) {
- hash += b0;
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
+ template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data)
+ {
+ StringHasher hasher;
+
+ while (true) {
+ UChar b0 = Converter(*data++);
+ if (!b0)
+ break;
+ UChar b1 = Converter(*data++);
+ if (!b1) {
+ hasher.addCharacter(b0);
+ break;
+ }
+
+ hasher.addCharacters(b0, b1);
}
- hash += b0;
- unsigned tmp = (b1 << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2;
- hash += hash >> 11;
+
+ return hasher.hash();
+ }
+
+ template<typename T> static inline unsigned createHash(const T* data, unsigned length)
+ {
+ return createHash<T, defaultCoverter>(data, length);
}
- // Force "avalanching" of final 127 bits.
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
+ template<typename T> static inline unsigned createHash(const T* data)
+ {
+ return createHash<T, defaultCoverter>(data);
+ }
- hash &= 0x7fffffff;
+ template<size_t length> static inline unsigned createBlobHash(const void* data)
+ {
+ COMPILE_ASSERT(!(length % 4), length_must_be_a_multible_of_four);
+ return createHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
+ }
- // This avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked.
- if (hash == 0)
- hash = 0x40000000;
+private:
+ static inline UChar defaultCoverter(UChar ch)
+ {
+ return ch;
+ }
+
+ static inline UChar defaultCoverter(char ch)
+ {
+ return static_cast<unsigned char>(ch);
+ }
+
+ inline void addCharactersToHash(UChar a, UChar b)
+ {
+ m_hash += a;
+ unsigned tmp = (b << 11) ^ m_hash;
+ m_hash = (m_hash << 16) ^ tmp;
+ m_hash += m_hash >> 11;
+ }
- return hash;
-}
+ unsigned m_hash;
+ bool m_hasPendingCharacter;
+ UChar m_pendingCharacter;
+};
} // namespace WTF
diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp
index 98286d3..0017a6f 100644
--- a/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -241,12 +241,6 @@ ThreadIdentifier currentThread()
Mutex::Mutex()
{
-#if PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_DEFAULT
-
- pthread_mutex_init(&m_mutex, 0);
-
-#else
-
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
@@ -254,8 +248,6 @@ Mutex::Mutex()
pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr);
-
-#endif
}
Mutex::~Mutex()
diff --git a/JavaScriptCore/wtf/gobject/GOwnPtr.cpp b/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
index da0d839..8dcfb9e 100644
--- a/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
@@ -19,6 +19,8 @@
#include "config.h"
#include "GOwnPtr.h"
+#if ENABLE(GLIB_SUPPORT)
+
#include <gio/gio.h>
#include <glib.h>
@@ -65,3 +67,5 @@ template <> void freeOwnedGPtr<GFile>(GFile* ptr)
g_object_unref(ptr);
}
} // namespace WTF
+
+#endif // ENABLE(GLIB_SUPPORT)
diff --git a/JavaScriptCore/wtf/gobject/GOwnPtr.h b/JavaScriptCore/wtf/gobject/GOwnPtr.h
index e04ee9d..cec3e43 100644
--- a/JavaScriptCore/wtf/gobject/GOwnPtr.h
+++ b/JavaScriptCore/wtf/gobject/GOwnPtr.h
@@ -22,6 +22,8 @@
#ifndef GOwnPtr_h
#define GOwnPtr_h
+#if ENABLE(GLIB_SUPPORT)
+
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
@@ -135,4 +137,7 @@ template <typename T> inline void freeOwnedGPtr(T* ptr)
using WTF::GOwnPtr;
+#endif // ENABLE(GLIB_SUPPORT)
+
#endif // GOwnPtr_h
+
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
index 14f7cf4..085684e 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
@@ -19,6 +19,8 @@
#include "config.h"
#include "GRefPtr.h"
+#if ENABLE(GLIB_SUPPORT)
+
#include <glib.h>
namespace WTF {
@@ -80,3 +82,5 @@ template <> void derefPlatformPtr(GSource* ptr)
}
} // namespace WTF
+
+#endif // ENABLE(GLIB_SUPPORT)
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h
index ede0a7a..4efd9be 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.h
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.h
@@ -23,6 +23,8 @@
#ifndef WTF_GRefPtr_h
#define WTF_GRefPtr_h
+#if ENABLE(GLIB_SUPPORT)
+
#include "AlwaysInline.h"
#include "PlatformRefPtr.h"
#include <algorithm>
@@ -54,4 +56,6 @@ template <typename T> inline void derefPlatformPtr(T* ptr)
} // namespace WTF
+#endif // ENABLE(GLIB_SUPPORT)
+
#endif // WTF_GRefPtr_h
diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp
index 1981170..c8140d6 100644
--- a/JavaScriptCore/wtf/text/AtomicString.cpp
+++ b/JavaScriptCore/wtf/text/AtomicString.cpp
@@ -156,6 +156,11 @@ static inline bool equal(StringImpl* string, const UChar* characters, unsigned l
#endif
}
+bool operator==(const AtomicString& string, const Vector<UChar>& vector)
+{
+ return string.impl() && equal(string.impl(), vector.data(), vector.size());
+}
+
struct UCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
diff --git a/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h
index cfabde7..06e63f4 100644
--- a/JavaScriptCore/wtf/text/AtomicString.h
+++ b/JavaScriptCore/wtf/text/AtomicString.h
@@ -126,15 +126,19 @@ private:
inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); }
bool operator==(const AtomicString& a, const char* b);
+bool operator==(const AtomicString& a, const Vector<UChar>& b);
inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); }
inline bool operator==(const char* a, const AtomicString& b) { return b == a; }
inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); }
+inline bool operator==(const Vector<UChar>& a, const AtomicString& b) { return b == a; }
inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); }
inline bool operator!=(const AtomicString& a, const char *b) { return !(a == b); }
inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); }
+inline bool operator!=(const AtomicString& a, const Vector<UChar>& b) { return !(a == b); }
inline bool operator!=(const char* a, const AtomicString& b) { return !(b == a); }
inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); }
+inline bool operator!=(const Vector<UChar>& a, const AtomicString& b) { return !(a == b); }
inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); }
inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), b); }
diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h
index cec0b80..7025d9f 100644
--- a/JavaScriptCore/wtf/text/StringImpl.h
+++ b/JavaScriptCore/wtf/text/StringImpl.h
@@ -233,9 +233,9 @@ public:
unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
- static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
- static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); }
- static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
+ static unsigned computeHash(const UChar* data, unsigned length) { return WTF::StringHasher::createHash<UChar>(data, length); }
+ static unsigned computeHash(const char* data, unsigned length) { return WTF::StringHasher::createHash<char>(data, length); }
+ static unsigned computeHash(const char* data) { return WTF::StringHasher::createHash<char>(data); }
ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; }
diff --git a/JavaScriptCore/wtf/unicode/UTF8.cpp b/JavaScriptCore/wtf/unicode/UTF8.cpp
index 21d5856..40c5609 100644
--- a/JavaScriptCore/wtf/unicode/UTF8.cpp
+++ b/JavaScriptCore/wtf/unicode/UTF8.cpp
@@ -240,7 +240,7 @@ ConversionResult convertUTF8ToUTF16(
UChar* target = *targetStart;
while (source < sourceEnd) {
UChar32 ch = 0;
- int extraBytesToRead = UTF8SequenceLength(*source) - 1;
+ int extraBytesToRead = inlineUTF8SequenceLength(*source) - 1;
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted;
break;
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index c9e2e1c..547ed32 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -58,7 +58,7 @@ namespace QUnicodeTables {
QT_END_NAMESPACE
// ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
-#if defined(Q_OS_WIN) || COMPILER(WINSCW) || (COMPILER(RVCT) && OS(SYMBIAN))
+#if defined(Q_OS_WIN) || COMPILER(WINSCW) || (COMPILER(RVCT) && !OS(LINUX))
typedef wchar_t UChar;
#else
typedef uint16_t UChar;
diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp
index d50c6c8..17ffd8f 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -1106,6 +1106,10 @@ public:
input.next();
context->matchBegin = input.getPos();
+
+ if (currentTerm().alternative.onceThrough)
+ context->term += currentTerm().alternative.next;
+
MATCH_NEXT();
}
case ByteTerm::TypeBodyAlternativeEnd:
@@ -1257,7 +1261,7 @@ public:
PassOwnPtr<BytecodePattern> compile(BumpPointerAllocator* allocator)
{
- regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize);
+ regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize, m_pattern.m_body->m_alternatives[0]->onceThrough());
emitDisjunction(m_pattern.m_body);
regexEnd();
@@ -1462,10 +1466,10 @@ public:
}
}
- void regexBegin(unsigned numSubpatterns, unsigned callFrameSize)
+ void regexBegin(unsigned numSubpatterns, unsigned callFrameSize, bool onceThrough)
{
m_bodyDisjunction = adoptPtr(new ByteDisjunction(numSubpatterns, callFrameSize));
- m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin());
+ m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin(onceThrough));
m_bodyDisjunction->terms[0].frameLocation = 0;
m_currentAlternativeIndex = 0;
}
@@ -1475,11 +1479,11 @@ public:
closeBodyAlternative();
}
- void alternativeBodyDisjunction()
+ void alternativeBodyDisjunction(bool onceThrough)
{
int newAlternativeIndex = m_bodyDisjunction->terms.size();
m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex;
- m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction());
+ m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction(onceThrough));
m_currentAlternativeIndex = newAlternativeIndex;
}
@@ -1498,14 +1502,15 @@ public:
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
unsigned currentCountAlreadyChecked = inputCountAlreadyChecked;
+ PatternAlternative* alternative = disjunction->m_alternatives[alt];
+
if (alt) {
if (disjunction == m_pattern.m_body)
- alternativeBodyDisjunction();
+ alternativeBodyDisjunction(alternative->onceThrough());
else
alternativeDisjunction();
}
- PatternAlternative* alternative = disjunction->m_alternatives[alt];
unsigned minimumSize = alternative->m_minimumSize;
ASSERT(minimumSize >= parenthesesInputCountAlreadyChecked);
diff --git a/JavaScriptCore/yarr/RegexInterpreter.h b/JavaScriptCore/yarr/RegexInterpreter.h
index 4da9cc5..37f17fe 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.h
+++ b/JavaScriptCore/yarr/RegexInterpreter.h
@@ -94,6 +94,7 @@ struct ByteTerm {
struct {
int next;
int end;
+ bool onceThrough;
} alternative;
unsigned checkInputCount;
};
@@ -215,19 +216,21 @@ struct ByteTerm {
return ByteTerm(TypeBackReference, subpatternId, false, inputPos);
}
- static ByteTerm BodyAlternativeBegin()
+ static ByteTerm BodyAlternativeBegin(bool onceThrough)
{
ByteTerm term(TypeBodyAlternativeBegin);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = onceThrough;
return term;
}
- static ByteTerm BodyAlternativeDisjunction()
+ static ByteTerm BodyAlternativeDisjunction(bool onceThrough)
{
ByteTerm term(TypeBodyAlternativeDisjunction);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = onceThrough;
return term;
}
@@ -236,6 +239,7 @@ struct ByteTerm {
ByteTerm term(TypeBodyAlternativeEnd);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -244,6 +248,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeBegin);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -252,6 +257,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeDisjunction);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -260,6 +266,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeEnd);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp
index 8740130..1b80464 100644
--- a/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/JavaScriptCore/yarr/RegexJIT.cpp
@@ -986,10 +986,8 @@ class RegexGenerator : private MacroAssembler {
parenthesesState.plantJumpToBacktrackIfExists(this);
// A failure WITHIN the parens jumps here
parenthesesState.linkAlternativeBacktracks(this);
- if (term.invertOrCapture) {
+ if (term.invertOrCapture)
store32(Imm32(-1), Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
- store32(Imm32(-1), Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
- }
if (term.quantityType == QuantifierGreedy)
storeToFrame(Imm32(0), parenthesesFrameLocation);
@@ -1271,64 +1269,75 @@ 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.
- // If we get here, there the last input checked failed.
- notEnoughInputForPreviousAlternative.link(this);
-
- // Check if sufficent input available to run the next alternative
- notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
- // We are now in the correct state to enter the next alternative; this add is only required
- // to mirror and revert operation of the sub32, just below.
- add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
-
- // If we get here, there the last input checked passed.
- state.linkAlternativeBacktracks(this);
- // No need to check if we can run the next alternative, since it is shorter -
- // just update index.
- sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
- } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
+
+ countToCheckForFirstAlternative = nextAlternative->m_minimumSize;
+
// If we get here, there the last input checked failed.
- // If there is insufficient input to run the current alternative, and the next alternative is longer,
- // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
- // we had checked.
notEnoughInputForPreviousAlternative.link(this);
- add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
- notEnoughInputForPreviousAlternative.append(jump());
-
- // The next alternative is longer than the current one; check the difference.
- state.linkAlternativeBacktracks(this);
- notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
- } else { // CASE 3: Both alternatives are the same length.
- ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
-
- // If the next alterative is the same length as this one, then no need to check the input -
- // if there was sufficent input to run the current alternative then there is sufficient
- // input to run the next one; if not, there isn't.
+
state.linkAlternativeBacktracks(this);
- }
- if (setAlternativeLoopLabel) {
+ // Back up to start the looping alternatives.
+ if (countCheckedForCurrentAlternative)
+ sub32(Imm32(countCheckedForCurrentAlternative), index);
+
+ firstAlternative = Label(this);
+
+ state.checkedTotal = countToCheckForFirstAlternative;
+ if (countToCheckForFirstAlternative)
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative));
+
+ countCheckedForCurrentAlternative = countToCheckForFirstAlternative;
+
firstAlternativeInputChecked = Label(this);
- countToCheckForFirstAlternative = countToCheckForNextAlternative;
- setAlternativeLoopLabel = true;
+
+ setRepeatAlternativeLabels = true;
+ } else {
+ int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
+
+ if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
+ // If we get here, then the last input checked failed.
+ notEnoughInputForPreviousAlternative.link(this);
+
+ // Check if sufficent input available to run the next alternative
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+ // We are now in the correct state to enter the next alternative; this add is only required
+ // to mirror and revert operation of the sub32, just below.
+ add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+
+ // If we get here, then the last input checked passed.
+ state.linkAlternativeBacktracks(this);
+ // No need to check if we can run the next alternative, since it is shorter -
+ // just update index.
+ sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+ } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
+ // If we get here, then the last input checked failed.
+ // If there is insufficient input to run the current alternative, and the next alternative is longer,
+ // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
+ // we had checked.
+ notEnoughInputForPreviousAlternative.link(this);
+ add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
+ notEnoughInputForPreviousAlternative.append(jump());
+
+ // The next alternative is longer than the current one; check the difference.
+ state.linkAlternativeBacktracks(this);
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+ } else { // CASE 3: Both alternatives are the same length.
+ ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
+
+ // If the next alterative is the same length as this one, then no need to check the input -
+ // if there was sufficent input to run the current alternative then there is sufficient
+ // input to run the next one; if not, there isn't.
+ state.linkAlternativeBacktracks(this);
+ }
+ state.checkedTotal -= countCheckedForCurrentAlternative;
+ countCheckedForCurrentAlternative = countToCheckForNextAlternative;
+ state.checkedTotal += countCheckedForCurrentAlternative;
}
-
- state.checkedTotal -= countCheckedForCurrentAlternative;
- countCheckedForCurrentAlternative = countToCheckForNextAlternative;
- state.checkedTotal += countCheckedForCurrentAlternative;
}
}