summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-10-22 13:02:20 +0100
committerBen Murdoch <benm@google.com>2010-10-26 15:21:41 +0100
commita94275402997c11dd2e778633dacf4b7e630a35d (patch)
treee66f56c67e3b01f22c9c23cd932271ee9ac558ed /JavaScriptCore
parent09e26c78506587b3f5d930d7bc72a23287ffbec0 (diff)
downloadexternal_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.zip
external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.gz
external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.bz2
Merge WebKit at r70209: Initial merge by Git
Change-Id: Id23a68efa36e9d1126bcce0b137872db00892c8e
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/Android.mk2
-rw-r--r--JavaScriptCore/Android.v8.wtf.mk2
-rw-r--r--JavaScriptCore/CMakeLists.txt3
-rw-r--r--JavaScriptCore/ChangeLog1731
-rw-r--r--JavaScriptCore/Configurations/FeatureDefines.xcconfig10
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptCore/GNUmakefile.am13
-rw-r--r--JavaScriptCore/JavaScriptCore.exp23
-rw-r--r--JavaScriptCore/JavaScriptCore.gypi9
-rw-r--r--JavaScriptCore/JavaScriptCore.pri6
-rw-r--r--JavaScriptCore/JavaScriptCore.pro1
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def21
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj16
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops2
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make28
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj28
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj4
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj67
-rw-r--r--JavaScriptCore/assembler/ARMv7Assembler.cpp5
-rw-r--r--JavaScriptCore/assembler/ARMv7Assembler.h324
-rw-r--r--JavaScriptCore/assembler/LinkBuffer.h73
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerARMv7.h27
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.cpp64
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h17
-rw-r--r--JavaScriptCore/bytecode/EvalCodeCache.h8
-rw-r--r--JavaScriptCore/bytecode/Opcode.h6
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp94
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h13
-rw-r--r--JavaScriptCore/bytecompiler/NodesCodegen.cpp18
-rw-r--r--JavaScriptCore/debugger/Debugger.cpp2
-rw-r--r--JavaScriptCore/debugger/DebuggerCallFrame.cpp2
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp229
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h13
-rw-r--r--JavaScriptCore/jit/JIT.cpp20
-rw-r--r--JavaScriptCore/jit/JIT.h10
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp600
-rw-r--r--JavaScriptCore/jit/JITCall.cpp4
-rw-r--r--JavaScriptCore/jit/JITCall32_64.cpp11
-rw-r--r--JavaScriptCore/jit/JITInlineMethods.h6
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp119
-rw-r--r--JavaScriptCore/jit/JITOpcodes32_64.cpp77
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess.cpp14
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp104
-rw-r--r--JavaScriptCore/jit/JITStubs.h5
-rw-r--r--JavaScriptCore/jit/JSInterfaceJIT.h32
-rw-r--r--JavaScriptCore/jit/SpecializedThunkJIT.h13
-rw-r--r--JavaScriptCore/jit/ThunkGenerators.cpp10
-rw-r--r--JavaScriptCore/parser/ASTBuilder.h7
-rw-r--r--JavaScriptCore/parser/JSParser.cpp459
-rw-r--r--JavaScriptCore/parser/JSParser.h8
-rw-r--r--JavaScriptCore/parser/Lexer.cpp18
-rw-r--r--JavaScriptCore/parser/Lexer.h5
-rw-r--r--JavaScriptCore/parser/Nodes.cpp12
-rw-r--r--JavaScriptCore/parser/Nodes.h11
-rw-r--r--JavaScriptCore/parser/Parser.cpp16
-rw-r--r--JavaScriptCore/parser/Parser.h15
-rw-r--r--JavaScriptCore/parser/SyntaxChecker.h103
-rw-r--r--JavaScriptCore/profiler/Profiler.cpp4
-rw-r--r--JavaScriptCore/runtime/Arguments.cpp66
-rw-r--r--JavaScriptCore/runtime/Arguments.h12
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp7
-rw-r--r--JavaScriptCore/runtime/Collector.cpp18
-rw-r--r--JavaScriptCore/runtime/Collector.h2
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.cpp1
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--JavaScriptCore/runtime/DateConversion.cpp4
-rw-r--r--JavaScriptCore/runtime/Error.cpp43
-rw-r--r--JavaScriptCore/runtime/Error.h2
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp17
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h1
-rw-r--r--JavaScriptCore/runtime/Executable.cpp48
-rw-r--r--JavaScriptCore/runtime/Executable.h33
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp10
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp5
-rw-r--r--JavaScriptCore/runtime/JSActivation.h1
-rw-r--r--JavaScriptCore/runtime/JSCell.h14
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp86
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp5
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h5
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h10
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp8
-rw-r--r--JavaScriptCore/runtime/JSImmediate.h65
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.cpp70
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h165
-rw-r--r--JavaScriptCore/runtime/JSONObject.cpp32
-rw-r--r--JavaScriptCore/runtime/JSObject.cpp23
-rw-r--r--JavaScriptCore/runtime/JSObject.h60
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.cpp5
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.h1
-rw-r--r--JavaScriptCore/runtime/JSStringBuilder.h12
-rw-r--r--JavaScriptCore/runtime/JSValue.h3
-rw-r--r--JavaScriptCore/runtime/JSZombie.h1
-rw-r--r--JavaScriptCore/runtime/LiteralParser.cpp6
-rw-r--r--JavaScriptCore/runtime/NumberObject.h4
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.cpp12
-rw-r--r--JavaScriptCore/runtime/Operations.h6
-rw-r--r--JavaScriptCore/runtime/PutPropertySlot.h5
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--JavaScriptCore/runtime/RegExpObject.cpp4
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.cpp3
-rw-r--r--JavaScriptCore/runtime/StrictEvalActivation.cpp51
-rw-r--r--JavaScriptCore/runtime/StrictEvalActivation.h43
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp49
-rw-r--r--JavaScriptCore/runtime/UStringBuilder.h (renamed from JavaScriptCore/runtime/StringBuilder.h)62
-rw-r--r--JavaScriptCore/runtime/UStringConcatenate.h125
-rw-r--r--JavaScriptCore/shell/CMakeLists.txt (renamed from JavaScriptCore/jsc/CMakeLists.txt)0
-rw-r--r--JavaScriptCore/shell/CMakeListsEfl.txt (renamed from JavaScriptCore/jsc/CMakeListsEfl.txt)0
-rw-r--r--JavaScriptCore/wscript8
-rw-r--r--JavaScriptCore/wtf/CMakeLists.txt2
-rw-r--r--JavaScriptCore/wtf/CMakeListsEfl.txt15
-rw-r--r--JavaScriptCore/wtf/CurrentTime.h1
-rw-r--r--JavaScriptCore/wtf/DateMath.cpp159
-rw-r--r--JavaScriptCore/wtf/DateMath.h4
-rw-r--r--JavaScriptCore/wtf/DecimalNumber.cpp199
-rw-r--r--JavaScriptCore/wtf/DecimalNumber.h104
-rw-r--r--JavaScriptCore/wtf/FastAllocBase.h67
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp16
-rw-r--r--JavaScriptCore/wtf/MD5.cpp2
-rw-r--r--JavaScriptCore/wtf/Noncopyable.h2
-rw-r--r--JavaScriptCore/wtf/NullPtr.h48
-rw-r--r--JavaScriptCore/wtf/OwnArrayPtr.h2
-rw-r--r--JavaScriptCore/wtf/OwnPtr.h2
-rw-r--r--JavaScriptCore/wtf/PassOwnArrayPtr.h2
-rw-r--r--JavaScriptCore/wtf/PassOwnPtr.h2
-rw-r--r--JavaScriptCore/wtf/PassRefPtr.h2
-rw-r--r--JavaScriptCore/wtf/Platform.h18
-rw-r--r--JavaScriptCore/wtf/RandomNumber.cpp10
-rw-r--r--JavaScriptCore/wtf/RandomNumberSeed.h2
-rw-r--r--JavaScriptCore/wtf/RefPtr.h2
-rw-r--r--JavaScriptCore/wtf/RetainPtr.h2
-rw-r--r--JavaScriptCore/wtf/StringHasher.h (renamed from JavaScriptCore/wtf/StringHashFunctions.h)6
-rw-r--r--JavaScriptCore/wtf/TCSpinLock.h11
-rw-r--r--JavaScriptCore/wtf/TypeTraits.cpp3
-rw-r--r--JavaScriptCore/wtf/TypeTraits.h9
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.h6
-rw-r--r--JavaScriptCore/wtf/brew/RefPtrBrew.h53
-rw-r--r--JavaScriptCore/wtf/brew/ShellBrew.h14
-rw-r--r--JavaScriptCore/wtf/dtoa.cpp4
-rw-r--r--JavaScriptCore/wtf/dtoa.h3
-rw-r--r--JavaScriptCore/wtf/text/CString.cpp4
-rw-r--r--JavaScriptCore/wtf/text/CString.h10
-rw-r--r--JavaScriptCore/wtf/text/StringBuffer.h17
-rw-r--r--JavaScriptCore/wtf/text/StringBuilder.cpp172
-rw-r--r--JavaScriptCore/wtf/text/StringBuilder.h139
-rw-r--r--JavaScriptCore/wtf/text/StringConcatenate.h (renamed from JavaScriptCore/runtime/StringConcatenate.h)63
-rw-r--r--JavaScriptCore/wtf/text/StringHash.h95
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.cpp2
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.h6
-rw-r--r--JavaScriptCore/wtf/text/WTFString.cpp12
-rw-r--r--JavaScriptCore/wtf/unicode/Unicode.h2
-rw-r--r--JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp181
-rw-r--r--JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h194
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h32
-rw-r--r--JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp38
-rw-r--r--JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h286
-rw-r--r--JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp173
-rw-r--r--JavaScriptCore/wtf/url/src/URLCharacterTypes.h61
-rw-r--r--JavaScriptCore/wtf/url/src/URLEscape.cpp39
-rw-r--r--JavaScriptCore/wtf/url/src/URLEscape.h49
-rw-r--r--JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h107
-rw-r--r--JavaScriptCore/wtf/wtf.pri2
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.cpp50
164 files changed, 6103 insertions, 2170 deletions
diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index 959fbc4..c690477 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -166,6 +166,7 @@ LOCAL_SRC_FILES := \
wtf/ByteArray.cpp \
wtf/CurrentTime.cpp \
wtf/DateMath.cpp \
+ wtf/DecimalNumber.cpp \
wtf/FastMalloc.cpp \
wtf/HashTable.cpp \
wtf/MD5.cpp \
@@ -185,6 +186,7 @@ LOCAL_SRC_FILES := \
\
wtf/text/AtomicString.cpp \
wtf/text/CString.cpp \
+ wtf/text/StringBuilder.cpp \
wtf/text/StringImpl.cpp \
wtf/text/StringStatics.cpp \
wtf/text/WTFString.cpp \
diff --git a/JavaScriptCore/Android.v8.wtf.mk b/JavaScriptCore/Android.v8.wtf.mk
index 16554b1..a9c8a3b 100644
--- a/JavaScriptCore/Android.v8.wtf.mk
+++ b/JavaScriptCore/Android.v8.wtf.mk
@@ -36,6 +36,7 @@ LOCAL_SRC_FILES := \
wtf/ByteArray.cpp \
wtf/CurrentTime.cpp \
wtf/DateMath.cpp \
+ wtf/DecimalNumber.cpp \
wtf/FastMalloc.cpp \
wtf/HashTable.cpp \
wtf/MD5.cpp \
@@ -55,6 +56,7 @@ LOCAL_SRC_FILES := \
\
wtf/text/AtomicString.cpp \
wtf/text/CString.cpp \
+ wtf/text/StringBuidler.cpp \
wtf/text/StringImpl.cpp \
wtf/text/StringStatics.cpp \
wtf/text/WTFString.cpp \
diff --git a/JavaScriptCore/CMakeLists.txt b/JavaScriptCore/CMakeLists.txt
index 89c9ef1..90067a4 100644
--- a/JavaScriptCore/CMakeLists.txt
+++ b/JavaScriptCore/CMakeLists.txt
@@ -157,6 +157,7 @@ SET(JavaScriptCore_SOURCES
runtime/RopeImpl.cpp
runtime/ScopeChain.cpp
runtime/SmallStrings.cpp
+ runtime/StrictEvalActivation.cpp
runtime/StringConstructor.cpp
runtime/StringObject.cpp
runtime/StringPrototype.cpp
@@ -254,7 +255,7 @@ SOURCE_GROUP(yarr "yarr/")
SOURCE_GROUP(wtf "wtf/")
ADD_SUBDIRECTORY(wtf)
-ADD_SUBDIRECTORY(jsc)
+ADD_SUBDIRECTORY(shell)
WEBKIT_WRAP_SOURCELIST(${JavaScriptCore_SOURCES})
INCLUDE_DIRECTORIES(${JavaScriptCore_INCLUDE_DIRECTORIES})
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index bbdf703..95bf475 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,1734 @@
+2010-10-20 Simon Fraser <simon.fraser@apple.com>
+
+ Fix the EFL build.
+
+ * wtf/CMakeLists.txt:
+
+2010-10-20 Simon Fraser <simon.fraser@apple.com>
+
+ Fix Windows build: export needed symbols.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-10-19 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47851
+
+ Add methods to DecimalNumber to return the buffer length
+ required for decimal and exponential output.
+
+ Make some of the DecimalNumber code non-inline (no
+ effect on Sunspider), adding DecimalNumber.cpp to various
+ build systems.
+
+ Make some DecimalNumber methods 'const'.
+
+ * Android.mk:
+ * Android.v8.wtf.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/NumberPrototype.cpp:
+ (JSC::numberProtoFuncToExponential):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToPrecision):
+ * wtf/DecimalNumber.cpp: Added.
+ (WTF::DecimalNumber::bufferLengthForStringDecimal):
+ (WTF::DecimalNumber::bufferLengthForStringExponential):
+ (WTF::DecimalNumber::toStringDecimal):
+ (WTF::DecimalNumber::toStringExponential):
+ * wtf/DecimalNumber.h:
+ (WTF::DecimalNumber::sign):
+ (WTF::DecimalNumber::exponent):
+ (WTF::DecimalNumber::significand):
+ (WTF::DecimalNumber::precision):
+ * wtf/dtoa.cpp:
+ (WTF::dtoa):
+ * wtf/dtoa.h:
+ * wtf/wtf.pri:
+
+2010-10-20 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r70165.
+ http://trac.webkit.org/changeset/70165
+ https://bugs.webkit.org/show_bug.cgi?id=48007
+
+ It broke tests on Qt bot (Requested by Ossy on #webkit).
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/text/TextPosition.h: Removed.
+
+2010-10-20 Brian Weinstein <bweinstein@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Fix the Windows build after r70165. Move the copying of JavaScript headers from JavaScriptCore's post-build
+ step to JavaScriptCoreGenerated, so the copying is done even when a cpp file in JavaScriptCore is changed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
+
+2010-10-20 Dumitru Daniliuc <dumi@chromium.org>
+
+ Unreviewed, fixing the Win build.
+
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+
+2010-10-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=41948
+ REGRESSION(r60392): Registerfile can be unwound too far following an exception
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException): Walk the stack to calculate the high
+ water mark currently in use. It's not safe to assume that the current
+ CallFrame's high water mark is the highest high water mark because
+ calls do not always set up at the end of a CallFrame. A large caller
+ CallFrame can encompass a small callee CallFrame.
+
+2010-10-20 Peter Rybin <peter.rybin@gmail.com>
+
+ Reviewed by Adam Barth.
+
+ HTML parser should provide script column position within HTML document to JavaScript engine
+ https://bugs.webkit.org/show_bug.cgi?id=45271
+
+ Adds TextPosition* classes -- a structure that stores line/column/generation
+ level coordinates inside text document. Adds *BasedNumber classes -- typesafe int
+ wrappers that emphasize whether int number is used as zero-based or
+ one-based.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/text/TextPosition.h: Added.
+ (WTF::TextPosition::TextPosition):
+ (WTF::TextPosition::minimumPosition):
+ (WTF::TextPosition::belowRangePosition):
+ (WTF::ZeroBasedNumber::fromZeroBasedInt):
+ (WTF::ZeroBasedNumber::ZeroBasedNumber):
+ (WTF::ZeroBasedNumber::zeroBasedInt):
+ (WTF::ZeroBasedNumber::base):
+ (WTF::ZeroBasedNumber::belowBase):
+ (WTF::OneBasedNumber::fromOneBasedInt):
+ (WTF::OneBasedNumber::OneBasedNumber):
+ (WTF::OneBasedNumber::oneBasedInt):
+ (WTF::OneBasedNumber::convertAsZeroBasedInt):
+ (WTF::OneBasedNumber::convertToZeroBased):
+ (WTF::OneBasedNumber::base):
+ (WTF::OneBasedNumber::belowBase):
+ (WTF::toZeroBasedTextPosition):
+ (WTF::toOneBasedTextPosition):
+ (WTF::ZeroBasedNumber::convertToOneBased):
+
+2010-10-19 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by David Kilzer.
+
+ [BREWMP] Turn off JIT for simulator build
+ https://bugs.webkit.org/show_bug.cgi?id=47937
+
+ We don't need to test x86 JIT.
+
+ * wtf/Platform.h:
+
+2010-10-19 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove support for JSVALUE32 from JSC
+ https://bugs.webkit.org/show_bug.cgi?id=47948
+
+ Remove all the code for supporting JSVALUE32 from JSC.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_lshift):
+ (JSC::JIT::emitSlow_op_lshift):
+ (JSC::JIT::emit_op_rshift):
+ (JSC::JIT::emitSlow_op_rshift):
+ (JSC::JIT::emit_op_urshift):
+ (JSC::JIT::emitSlow_op_urshift):
+ (JSC::JIT::emit_op_jnless):
+ (JSC::JIT::emitSlow_op_jnless):
+ (JSC::JIT::emit_op_jless):
+ (JSC::JIT::emitSlow_op_jless):
+ (JSC::JIT::emit_op_jlesseq):
+ (JSC::JIT::emitSlow_op_jlesseq):
+ (JSC::JIT::emit_op_bitand):
+ (JSC::JIT::emit_op_post_inc):
+ (JSC::JIT::emit_op_post_dec):
+ (JSC::JIT::emit_op_pre_inc):
+ (JSC::JIT::emit_op_pre_dec):
+ (JSC::JIT::emit_op_mod):
+ (JSC::JIT::emitSlow_op_mod):
+ * jit/JITCall.cpp:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetFromCallFrameHeaderPtr):
+ (JSC::JIT::emitGetFromCallFrameHeader32):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_if_lesseq):
+ (JSC::JIT::emit_op_bitnot):
+ (JSC::JIT::emit_op_next_pname):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ * jit/JITStubs.h:
+ * jit/JSInterfaceJIT.h:
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::tagReturnAsInt32):
+ * jit/ThunkGenerators.cpp:
+ (JSC::sqrtThunkGenerator):
+ (JSC::powThunkGenerator):
+ * runtime/Collector.cpp:
+ (JSC::isPossibleCell):
+ (JSC::typeName):
+ * runtime/JSCell.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.h:
+ (JSC::Structure::prototypeForLookup):
+ * runtime/JSImmediate.h:
+ (JSC::reinterpretIntptrToDouble):
+ (JSC::JSImmediate::isIntegerNumber):
+ (JSC::JSImmediate::isDouble):
+ (JSC::JSImmediate::areBothImmediateIntegerNumbers):
+ (JSC::JSImmediate::makeDouble):
+ (JSC::JSImmediate::doubleValue):
+ (JSC::JSImmediate::toBoolean):
+ (JSC::JSImmediate::fromNumberOutsideIntegerRange):
+ (JSC::JSImmediate::from):
+ (JSC::JSImmediate::toDouble):
+ (JSC::JSFastMath::rightShiftImmediateNumbers):
+ * runtime/JSNumberCell.cpp:
+ * runtime/JSNumberCell.h:
+ * runtime/JSObject.h:
+ (JSC::JSObject::JSObject):
+ * runtime/JSValue.h:
+ * runtime/NumberObject.h:
+ * wtf/Platform.h:
+
+2010-10-19 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ BytecodeGenerator::m_lastOpcodePosition must be initialized in all constructors
+ https://bugs.webkit.org/show_bug.cgi?id=47920
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Add missing member initialization.
+
+2010-10-19 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by David Kilzer.
+
+ RVCT fails to compile DateMath.cpp due to overloaded function pow
+ https://bugs.webkit.org/show_bug.cgi?id=47844
+
+ Choose std::pow(double, double) among multiple overloaded pow functions
+ to fix build for RVCT.
+
+ * wtf/DateMath.cpp:
+ (WTF::parseES5DateFromNullTerminatedCharacters):
+
+2010-10-19 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by David Kilzer.
+
+ Use UChar instead of wchar_t in UnicodeWinCE
+ https://bugs.webkit.org/show_bug.cgi?id=47904
+
+ Make UnicodeWinCE more portable, so we can use it for other ports too.
+
+ * wtf/unicode/wince/UnicodeWinCE.cpp:
+ (WTF::Unicode::toLower):
+ (WTF::Unicode::toUpper):
+ (WTF::Unicode::foldCase):
+ (WTF::Unicode::isPrintableChar):
+ (WTF::Unicode::isSpace):
+ (WTF::Unicode::isLetter):
+ (WTF::Unicode::isUpper):
+ (WTF::Unicode::isLower):
+ (WTF::Unicode::isDigit):
+ (WTF::Unicode::isPunct):
+ (WTF::Unicode::isAlphanumeric):
+ (WTF::Unicode::toTitleCase):
+ (WTF::Unicode::mirroredChar):
+ (WTF::Unicode::digitValue):
+ * wtf/unicode/wince/UnicodeWinCE.h:
+ (WTF::Unicode::isSeparatorSpace):
+ (WTF::Unicode::isHighSurrogate):
+ (WTF::Unicode::isLowSurrogate):
+ (WTF::Unicode::umemcasecmp):
+ (WTF::Unicode::surrogateToUcs4):
+
+2010-10-19 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix style of UnicodeWinCE
+ https://bugs.webkit.org/show_bug.cgi?id=47818
+
+ * wtf/unicode/wince/UnicodeWinCE.cpp:
+ (WTF::Unicode::toLower):
+ (WTF::Unicode::toUpper):
+ * wtf/unicode/wince/UnicodeWinCE.h:
+
+2010-10-18 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ * GNUmakefile.am: add missing file.
+
+2010-10-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Strict mode: Functions created with the function constructor don't implement strict mode semantics
+ https://bugs.webkit.org/show_bug.cgi?id=47860
+
+ When creating the FunctionExecutable for a new function the function constructor
+ was always passing false for whether or not a function was strict, rather than
+ using the information from the freshly parsed function itself.
+
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::fromGlobalCode):
+
+2010-10-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Strict mode: |this| should be undefined if it is not explicitly provided
+ https://bugs.webkit.org/show_bug.cgi?id=47833
+
+ To make strict mode behave correctly we want to pass undefined instead of null
+ as the default this value. This has no impact on behaviour outside of strict
+ mode as both values are replaced with the global object if necessary.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::FunctionCallValueNode::emitBytecode):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::CallFunctionCallDotNode::emitBytecode):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+
+
+2010-10-18 Darin Adler <darin@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Make a nullptr that works with OwnPtr and RefPtr
+ https://bugs.webkit.org/show_bug.cgi?id=47756
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added NullPtr.h.
+
+ * wtf/NullPtr.h: Added.
+
+ * wtf/OwnArrayPtr.h: Add an overload of = taking nullptr.
+ * wtf/OwnPtr.h: Ditto.
+ * wtf/PassOwnArrayPtr.h: Ditto.
+ * wtf/PassOwnPtr.h: Ditto.
+ * wtf/PassRefPtr.h: Ditto.
+ * wtf/RefPtr.h: Ditto.
+ * wtf/RetainPtr.h: Ditto.
+
+2010-10-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Strict mode: JIT doesn't check for |this| being an immediate before dereferencing
+ https://bugs.webkit.org/show_bug.cgi?id=47826
+
+ There's no guarantee that |this| will be a cell in a strict mode function, so
+ don't claim that it is.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isKnownNotImmediate):
+
+2010-10-18 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ if (0) throw "x" ; else { } throws parse error after r69906
+ https://bugs.webkit.org/show_bug.cgi?id=47807
+
+ r69906 introduced a bug: the semicolon is not parsed after a throw
+ expression anymore. Thus, the semicolon terminates the "if" parsing
+ in the example above, and the else token results a parse error.
+
+ * parser/JSParser.cpp:
+ (JSC::JSParser::parseThrowStatement):
+
+2010-10-18 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Andreas Kling.
+
+ Remove some unnecessary lines of code from Parser.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=47816
+
+ * parser/Parser.cpp:
+
+2010-10-18 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Build broken with JIT disabled
+ https://bugs.webkit.org/show_bug.cgi?id=47801
+
+ This is a regression caused by r69940.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolveBase):
+
+2010-10-18 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Change FastAllocBase implementation into a macro
+ https://bugs.webkit.org/show_bug.cgi?id=42998
+
+ It was investigated in bug #33896 that inheriting classes from FastAllocBase
+ can result in objects getting larger which leads to memory regressions.
+ Using a macro instead of inheriting classes from FastAllocBase would solve the issue.
+
+ * wtf/FastAllocBase.h: Add a WTF_MAKE_FAST_ALLOCATED macro
+
+2010-10-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Strict mode: arguments is not valid as the base expression for pre- or post-fix expressions
+ https://bugs.webkit.org/show_bug.cgi?id=47791
+
+ Simple fix, check for arguments in addition to eval.
+
+ * parser/JSParser.cpp:
+ (JSC::JSParser::parseUnaryExpression):
+
+2010-10-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Strict mode: Assignment that would create a global should be a late ReferenceError, not a syntax failure
+ https://bugs.webkit.org/show_bug.cgi?id=47788
+
+ Fixing this required a couple of changes:
+ * resolve_base now has a flag to indicate whether it is being used for a put in strict mode.
+ this allows us to throw an exception when we're doing a completely generic resolve for
+ assignment, and that assignment would create a new global.
+ * There is a new opcode 'op_ensure_property_exists' that is used to determine whether
+ the property being assigned to already exists on the global object. This currently
+ has no caching, but such caching could be added relatively trivially. It is only used
+ in the case where we know that a property will be placed on the global object, and
+ we cannot verify that the property already exists.
+
+ In the jit we plant a call to cti_op_resolve_base_strict_put in the effected case rather
+ than making op_resolve_base have an additional runtime branch.
+
+ There's also a new helper function to create the exception for the invalid assignment.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ * parser/JSParser.cpp:
+ (JSC::JSParser::parseProgram):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createErrorForInvalidGlobalAssignment):
+ * runtime/ExceptionHelpers.h:
+ * runtime/Operations.h:
+ (JSC::resolveBase):
+
+2010-10-17 Simon Fraser <simon.fraser@apple.com>
+
+ First part of fix for Windows build failure. Will wait for the
+ next set of link errors to determine the mangled forms for dtoaRoundSF
+ and dtoaRoundDP.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-10-17 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Very large and small numbers fail to round-trip through CSS
+ https://bugs.webkit.org/show_bug.cgi?id=20674
+
+ New exports required to use DecimalNumber in WebCore.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-10-16 Kyusun Kim <maniagoon@company100.net>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add using declarations for currentTimeMS() and parseDateFromNullTerminatedCharacters()
+ https://bugs.webkit.org/show_bug.cgi?id=47758
+
+ * wtf/CurrentTime.h:
+ * wtf/DateMath.h:
+
+2010-10-16 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Rename StringHasherFunctions.h to StringHasher.h
+ https://bugs.webkit.org/show_bug.cgi?id=47200
+
+ Now StringHasherFunctions.h only contains the StringHasher class, so rename it to the correct name.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/StringHashFunctions.h: Removed.
+ * wtf/StringHasher.h: Copied from JavaScriptCore/wtf/StringHashFunctions.h.
+ * wtf/text/StringHash.h:
+ * wtf/text/StringImpl.h:
+
+2010-10-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Automatic Semicolon Insertion incorrectly inserts semicolon after break, continue, and return followed by a newline
+ https://bugs.webkit.org/show_bug.cgi?id=47762
+
+ The old YACC parser depended on the lexer for some classes of semicolon insertion.
+ The new parser handles ASI entirely on its own so when the lexer inserts a semicolon
+ on its own the net result is a spurious semicolon in the input stream. This can result
+ in incorrect parsing in some cases:
+
+ if (0)
+ break
+ ;else {}
+
+ Would result in a parse failure as the output from the lexer is essentially
+
+ if (0)
+ break
+ ;;else
+
+ So the second semicolon is interpreted as a empty statement, which terminates the if,
+ making the else an error.
+
+
+ * parser/JSParser.cpp:
+ (JSC::JSParser::parseThrowStatement):
+ Parsing of throw statement was wrong, and only worked due to the weird behaviour
+ in the lexer
+ * parser/Lexer.cpp:
+ (JSC::Lexer::lex):
+ Remove bogus semicolon insertion from the newline handling
+
+2010-10-15 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Replace some String::format() usages by StringConcatenate in WebKit
+ https://bugs.webkit.org/show_bug.cgi?id=47714
+
+ * wtf/text/StringConcatenate.h: Add UChar specific StringTypeAdapter, to accept single UChars in makeString().
+
+2010-10-15 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Unreviewed build fix for Debug Leopard which is failng to compile after r69842.
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+
+2010-10-15 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ The parenthetical assertion checking isn't working in some cases with YARR
+ Interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=46893
+
+ Calculate the countToCheck value of a TypeParentheticalAssertion by
+ subtracting the number of characters which follows
+ a TypeParentheticalAssertion term with the number of characters which should
+ be matched by terms which are contained
+ in the TypeParentheticalAssertion term (minimumSize).
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+
+2010-10-14 Nathan Vander Wilt <nate@andyet.net>
+
+ Reviewed by Darin Adler.
+
+ Added parser for ECMAScript 5 standard date format, so Date.parse can handle RFC 3339 timestamps: https://bugs.webkit.org/show_bug.cgi?id=44632
+
+ * runtime/DateConversion.cpp:
+ (JSC::parseDate):
+ * wtf/DateMath.cpp:
+ (WTF::ymdhmsToSeconds):
+ (WTF::parseES5DateFromNullTerminatedCharacters):
+ * wtf/DateMath.h:
+
+2010-10-14 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Replace lots of String::format() usages by StringConcatenate
+ https://bugs.webkit.org/show_bug.cgi?id=47664
+
+ Add StringTypeAdapter<char> to accept single characters for makeString().
+
+ * wtf/text/StringConcatenate.h:
+ (WTF::makeString):
+
+2010-10-14 David Goodwin <david_goodwin@apple.com>
+
+ Reviewed by Darin Adler.
+
+ need way to measure size of JITed ARM code
+ https://bugs.webkit.org/show_bug.cgi?id=47121
+
+ * assembler/LinkBuffer.h:
+ (JSC::LinkBuffer::linkCode):
+ (JSC::LinkBuffer::dumpLinkStats):
+ (JSC::LinkBuffer::dumpCode):
+
+2010-10-14 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ The backreference checking isn't working in some cases with YARR Interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=46904
+
+ The Interpreter::matchBackReference() function returns true without matching
+ when a backreference points to the same parentheses where it is.
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::Interpreter::matchBackReference):
+
+2010-10-14 No'am Rosenthal <noam.rosenthal@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Text breaking is slow: enable ICU as an opt-in
+ https://bugs.webkit.org/show_bug.cgi?id=40332
+
+ Added a config flag that enables ICU as an opt-in instead of the Qt specific code.
+ Because of the inclusion of ICU headers, some explicit casting was necessary in UnicodeQt4.h
+
+ * JavaScriptCore.pri:
+ * wtf/unicode/qt4/UnicodeQt4.h:
+ (WTF::Unicode::toLower):
+ (WTF::Unicode::toUpper):
+ (WTF::Unicode::toTitleCase):
+ (WTF::Unicode::foldCase):
+ (WTF::Unicode::isPrintableChar):
+ (WTF::Unicode::isSeparatorSpace):
+ (WTF::Unicode::isPunct):
+ (WTF::Unicode::isLower):
+ (WTF::Unicode::mirroredChar):
+ (WTF::Unicode::combiningClass):
+ (WTF::Unicode::direction):
+ (WTF::Unicode::category):
+
+2010-10-14 Anton Faern <anton@bladehawke.com>
+
+ Reviewed by Csaba Osztrogonác.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47658
+ NetBSD was not included in the WTF_PLATFORM_FOO to WTF_OS_FOO
+ change. This means that OS(NETBSD) is also undefined.
+
+ * wtf/Platform.h: s/_PLATFORM_/_OS_/ for NetBSD
+
+2010-10-13 David Goodwin <david_goodwin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ ARMv7 JIT should generated conditional branches when possible
+ https://bugs.webkit.org/show_bug.cgi?id=47384
+
+ Use different jump padding sizes for conditional and unconditional
+ jumps (12 bytes and 10 bytes respectively). This allows the JIT to
+ include the IT instruction as part of the conditional jump sequence
+ which in turn allows it to optimize away the IT using an ARMv7
+ conditional branch instruction. Use 2-byte B(T1) and 4-byte B(T3) for
+ conditional branches when displacement is in range. Also use IT/B(T4)
+ for conditional branch when displacement does not fit in B(T3).
+
+ For unconditional jump, instruction selection options are:
+ B(T2), B(T4), MOVW/MOVT/BX. For conditional jump, instruction selection
+ options are: B(T1), B(T3), IT/B(T4), ITTT/MOVW/MOVT/BX.
+
+ * assembler/ARMv7Assembler.cpp:
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::JmpSrc::JmpSrc):
+ (JSC::ARMv7Assembler::ifThenElse):
+ (JSC::ARMv7Assembler::jumpSizeDelta):
+ (JSC::ARMv7Assembler::canCompact):
+ (JSC::ARMv7Assembler::computeJumpType):
+ (JSC::ARMv7Assembler::link):
+ (JSC::ARMv7Assembler::canBeJumpT1):
+ (JSC::ARMv7Assembler::canBeJumpT3):
+ (JSC::ARMv7Assembler::canBeJumpT4):
+ (JSC::ARMv7Assembler::linkJumpT1):
+ (JSC::ARMv7Assembler::linkJumpT3):
+ (JSC::ARMv7Assembler::linkJumpT4):
+ (JSC::ARMv7Assembler::linkConditionalJumpT4):
+ (JSC::ARMv7Assembler::linkBX):
+ (JSC::ARMv7Assembler::linkConditionalBX):
+ (JSC::ARMv7Assembler::linkJumpAbsolute):
+ * assembler/LinkBuffer.h:
+ (JSC::LinkBuffer::linkCode):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::canCompact):
+ (JSC::MacroAssemblerARMv7::computeJumpType):
+ (JSC::MacroAssemblerARMv7::jumpSizeDelta):
+ (JSC::MacroAssemblerARMv7::jump):
+ (JSC::MacroAssemblerARMv7::nearCall):
+ (JSC::MacroAssemblerARMv7::call):
+ (JSC::MacroAssemblerARMv7::ret):
+ (JSC::MacroAssemblerARMv7::tailRecursiveCall):
+ (JSC::MacroAssemblerARMv7::makeJump):
+ (JSC::MacroAssemblerARMv7::makeBranch):
+
+2010-10-13 Fridrich Strba <fridrich.strba@bluewin.ch>
+
+ Reviewed by Darin Adler.
+
+ Don't depend on Windows on sched_yield and sched.h
+ https://bugs.webkit.org/show_bug.cgi?id=45543
+
+ sched.h is part of pthreads and sched_yield is implemented
+ in pthreads-win32 as Sleep(0). This patch avoids a gratuitous
+ dependency on pthreads-win32 in this file.
+
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SlowLock):
+
+2010-10-13 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Port unicode
+ https://bugs.webkit.org/show_bug.cgi?id=45716
+
+ Brew MP port uses only the subset of ICU library to reduce the binary size.
+ Follow the WinCE's implementation.
+
+ * wtf/Platform.h:
+ * wtf/unicode/Unicode.h:
+ * wtf/unicode/brew/UnicodeBrew.cpp: Added.
+ (WTF::Unicode::toLower):
+ (WTF::Unicode::toUpper):
+ (WTF::Unicode::foldCase):
+ (WTF::Unicode::isPrintableChar):
+ (WTF::Unicode::isUpper):
+ (WTF::Unicode::isLower):
+ (WTF::Unicode::isDigit):
+ (WTF::Unicode::isPunct):
+ (WTF::Unicode::isAlphanumeric):
+ (WTF::Unicode::toTitleCase):
+ (WTF::Unicode::direction):
+ (WTF::Unicode::category):
+ (WTF::Unicode::decompositionType):
+ (WTF::Unicode::combiningClass):
+ (WTF::Unicode::mirroredChar):
+ (WTF::Unicode::digitValue):
+ (WTF::Unicode::isSpace):
+ (WTF::Unicode::isLetter):
+ * wtf/unicode/brew/UnicodeBrew.h: Added.
+ (WTF::Unicode::isArabicChar):
+ (WTF::Unicode::isSeparatorSpace):
+ (WTF::Unicode::hasLineBreakingPropertyComplexContext):
+ (WTF::Unicode::hasLineBreakingPropertyComplexContextOrIdeographic):
+ (WTF::Unicode::umemcasecmp):
+
+2010-10-13 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-10-13 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ [WTFURL] Add URLQueryCanonicalizer
+ https://bugs.webkit.org/show_bug.cgi?id=45088
+
+ This class canonicalizes the query component of URLs. The main tricky
+ bit there is the convertCharset function, which I've moved to a
+ templated dependency. There'll likely be more about that in future
+ patches.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/url/src/URLEscape.cpp: Added.
+ * wtf/url/src/URLEscape.h: Added.
+ (WTF::appendEscapedCharacter):
+ * wtf/url/src/URLQueryCanonicalizer.h: Added.
+ (WTF::URLQueryCanonicalizer::canonicalize):
+ (WTF::URLQueryCanonicalizer::isAllASCII):
+ (WTF::URLQueryCanonicalizer::appendRaw8BitQueryString):
+ (WTF::URLQueryCanonicalizer::convertToQueryEncoding):
+
+2010-10-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 43987 - Downloading using XHR is much slower than before
+ Change StringBuilder to use overcapacity in a StringImpl, rather than a Vector.
+ Fundamentally this should be the same (copies current contents to expand capacity,
+ rather than using a rope), but this approach allows the intermadiate state of the
+ String to be inspected in the buffer without copying to resolve.
+
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::appendQuotedString):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ Renamed StringBuilder::size() -> length() (to match other String types).
+
+ * runtime/UStringBuilder.h:
+ (JSC::UStringBuilder::append):
+ (JSC::UStringBuilder::toUString):
+ Update for changes in parent class, can just 'using' the append methods.
+
+ * wtf/text/StringBuilder.cpp: Added.
+ (WTF::StringBuilder::reifyString):
+ (WTF::StringBuilder::resize):
+ (WTF::StringBuilder::reserveCapacity):
+ (WTF::StringBuilder::allocateBuffer):
+ (WTF::StringBuilder::appendUninitialized):
+ (WTF::StringBuilder::append):
+ (WTF::StringBuilder::shrinkToFit):
+ * wtf/text/StringBuilder.h:
+ (WTF::StringBuilder::StringBuilder):
+ (WTF::StringBuilder::append):
+ (WTF::StringBuilder::toString):
+ (WTF::StringBuilder::toStringPreserveCapacity):
+ (WTF::StringBuilder::length):
+ (WTF::StringBuilder::isEmpty):
+ (WTF::StringBuilder::operator[]):
+ (WTF::StringBuilder::clear):
+ Class updated to use overcapacity in a StringImpl, rather than a Vector.
+
+ * Android.mk:
+ * Android.v8.wtf.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ * wtf/wtf.pri:
+
+2010-10-13 Adam Roben <aroben@apple.com>
+
+ Export tryFastRealloc for WebKit2's benefit
+
+ Rubber-stamped by Anders Carlsson.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Added
+ tryFastRealloc. Removed RegExpObject::info, which is now exported via
+ JS_EXPORTDATA.
+
+2010-10-13 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ [WTFURL] Add a mechanism for classifying types of characters
+ https://bugs.webkit.org/show_bug.cgi?id=45085
+
+ Various characters have different escaping rules depending on where
+ they are in URLs. This patch adds a table containing that information.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/url/src/URLCharacterTypes.cpp: Added.
+ * wtf/url/src/URLCharacterTypes.h: Added.
+ (WTF::URLCharacterTypes::isQueryChar):
+ (WTF::URLCharacterTypes::isIPv4Char):
+ (WTF::URLCharacterTypes::isHexChar):
+ (WTF::URLCharacterTypes::isCharOfType):
+
+2010-10-13 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Missing parameters for bytecode dump of next_pname
+ https://bugs.webkit.org/show_bug.cgi?id=47590
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump): add missing parameters to the dump.
+
+2010-10-13 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Add wtf/text/StringConcatenate
+ https://bugs.webkit.org/show_bug.cgi?id=47584
+
+ Move runtime/StringConcatenate.h to wtf/text, make it work for Strings too.
+ Add a special runtime/UStringConcatenate.h class that inherits from StringConcatenate, and extends it for use with UString.
+ Exactly the same design that has been followed while refactoring StringBuilder.
+
+ The UString variants can all be removed as soon as WTF::String & JSC::UString converge.
+
+ * GNUmakefile.am: Add wtf/text/StringConcatenate.h and runtime/UStringConcatenate.h.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * bytecode/CodeBlock.cpp: s/makeString/makeUString/
+ (JSC::escapeQuotes):
+ (JSC::valueToSourceString):
+ (JSC::constantName):
+ (JSC::idName):
+ (JSC::CodeBlock::registerName):
+ (JSC::regexpToSourceString):
+ (JSC::regexpName):
+ * bytecompiler/NodesCodegen.cpp: Ditto.
+ (JSC::substitute):
+ * profiler/Profiler.cpp: Ditto.
+ (JSC::Profiler::createCallIdentifier):
+ * runtime/ExceptionHelpers.cpp: Ditto.
+ (JSC::createUndefinedVariableError):
+ (JSC::createErrorMessage):
+ (JSC::createInvalidParamError):
+ * runtime/FunctionConstructor.cpp: Ditto.
+ (JSC::constructFunction):
+ * runtime/FunctionPrototype.cpp: Ditto.
+ (JSC::insertSemicolonIfNeeded):
+ * runtime/JSONObject.cpp: Ditto.
+ (JSC::Stringifier::indent):
+ * runtime/JSStringBuilder.h:
+ (JSC::jsMakeNontrivialString):
+ * runtime/RegExpConstructor.cpp: Ditto.
+ (JSC::constructRegExp):
+ * runtime/RegExpObject.cpp: Ditto.
+ (JSC::RegExpObject::match):
+ * runtime/RegExpPrototype.cpp: Ditto.
+ (JSC::regExpProtoFuncCompile):
+ * runtime/StringConcatenate.h: Removed.
+ * runtime/UStringConcatenate.h: Added. Only contains the StringTypeAdapter<JSC::UString> code and the makeUString variants, the rest lives in wtf/text/StringConcatenate.h
+ (JSC::makeUString):
+ * wtf/text/StringConcatenate.h: Copied from runtime/StringConcatenate.h.
+ (WTF::makeString):
+
+2010-10-12 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix.
+
+ * wtf/text/StringBuilder.h:
+ (WTF::StringBuilder::length):
+
+2010-10-12 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Unify JSC::StringBuilder & WebCore::StringBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=47538
+
+ Move runtime/StringBuilder.h to wtf/text/StringBuilder.h. Rename build() to toString() and return a WTF::String().
+ Move the append(const JSC::UString&) method into runtime/UStringBuilder.h.
+ UStringBuilder inherits from StringBuilder.h and adds append(const JSC::UString&) and UString toUString() functionality.
+
+ No new code, just move code around.
+
+ * GNUmakefile.am: Add wtf/text/StringBuilder.h / runtime/UStringBuilder.h. Remove runtime/StringBuilder.h.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::paramString): Use UStringBuilder, instead of StringBuilder. Rename build() -> toUString().
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction): Ditto.
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncUnescape): Ditto.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::stringify): Ditto.
+ (JSC::Stringifier::appendQuotedString): Ditto.
+ (JSC::Stringifier::appendStringifiedValue): Ditto.
+ (JSC::Stringifier::startNewLine): Ditto.
+ (JSC::Stringifier::Holder::appendNextProperty): Ditto.
+ * runtime/LiteralParser.cpp:
+ (JSC::LiteralParser::Lexer::lexString): Ditto.
+ * runtime/NumberPrototype.cpp: Remove unneeded JSStringBuilder.h / StringBuilder.h include.
+ * runtime/StringBuilder.h: Removed.
+ * runtime/UStringBuilder.h: Added. Inherits from WTF::StringBuilder, extending it by two methods.
+ (JSC::UStringBuilder::append): append(const JSC::UString&)
+ (JSC::UStringBuilder::toUString):
+ * wtf/text/StringBuilder.h: Copied from runtime/StringBuilder.h. Move JSC::UString parts into runtime/UStringBuilder.h
+ (WTF::StringBuilder::append): Renamed m_buffer to buffer everywhere.
+ (WTF::StringBuilder::isEmpty): Ditto (+ constify method).
+ (WTF::StringBuilder::reserveCapacity): Ditto.
+ (WTF::StringBuilder::resize): Ditto.
+ (WTF::StringBuilder::size): Ditto.
+ (WTF::StringBuilder::operator[]): Ditto.
+ (WTF::StringBuilder::toString): Ditto (+ renamed from build()). Returns a String, not an UString. The old build() method is now named toUString() and lives in UStringBuilder.
+
+2010-10-12 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Cleaned up the processing of replacements after regular expression
+ processing, especially the case where there wasn't a match.
+ Changed to use empty strings instead of computing a zero length sub
+ string.
+ https://bugs.webkit.org/show_bug.cgi?id=47506
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+ (JSC::stringProtoFuncReplace):
+
+2010-10-11 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Clang build fix after r69472.
+ https://bugs.webkit.org/show_bug.cgi?id=46523
+
+ * wtf/text/StringHash.h:
+
+2010-10-11 Oliver Hunt <oliver@apple.com>
+
+ Undo last minute change to 32bit build.
+
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_convert_this_strict):
+
+2010-10-11 Brian Weinstein <bweinstein@apple.com>
+
+ Build fix for Windows. Add a necessary export from r69516.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-10-11 Oliver Hunt <oliver@apple.com>
+
+ Fix interpreter build -- was broken by incorrect merge.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-10-01 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [ES5] Implement strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=10701
+
+ Initial strict mode implementation. This is the simplest
+ implementation that could possibly work and adds (hopefully)
+ all of the restrictions required by strict mode. There are
+ a number of inefficiencies, especially in the handling of
+ arguments and eval as smart implementations would make this
+ patch more complicated.
+
+ The SyntaxChecker AST builder has become somewhat more complex
+ as strict mode does require more parse tree information to
+ validate the syntax.
+
+ Summary of major changes to the parser:
+ * We track when we enter strict mode (this may come as a surprise)
+ * Strict mode actually requires a degree of AST knowledge to validate
+ so the SyntaxChecker now produces values that can be used to distinguish
+ "node" types.
+ * We now track variables that are written to. We do this to
+ statically identify writes to global properties that don't exist
+ and abort at that point. This should actually make it possible
+ to optimise some other cases in the future but for now it's
+ purely for validity checking. Currently writes are only tracked
+ in strict mode code.
+ * Labels are now tracked as it is now a syntax error to jump to a label
+ that does not exist (or to use break, continue, or return in a context
+ where they would be invalid).
+
+ Runtime changes:
+ * In order to get correct hanlding of the Arguments object all
+ strict mode functions that reference arguments create and tearoff
+ the arguments object on entry. This is not strictly necessary
+ but was the least work necessary to get the correct behaviour.
+ * PutPropertySlot now tracks whether it is being used for a strict
+ mode write, and if so Object::put will throw when a write can't be
+ completed.
+ * StrictEvalActivation was added as an "activation" object for strict
+ mode eval (so that strict eval does not introduce new variables into
+ the containing scope).
+
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isStrictMode):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::get):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+ (JSC::BytecodeGenerator::emitReturn):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::isStrictMode):
+ (JSC::BytecodeGenerator::makeFunction):
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_convert_this_strict):
+ (JSC::JIT::emitSlow_op_convert_this_strict):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_get_pnames):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::isResolve):
+ * parser/JSParser.cpp:
+ (JSC::JSParser::next):
+ (JSC::JSParser::startLoop):
+ (JSC::JSParser::endLoop):
+ (JSC::JSParser::startSwitch):
+ (JSC::JSParser::endSwitch):
+ (JSC::JSParser::setStrictMode):
+ (JSC::JSParser::strictMode):
+ (JSC::JSParser::isValidStrictMode):
+ (JSC::JSParser::declareParameter):
+ (JSC::JSParser::breakIsValid):
+ (JSC::JSParser::pushLabel):
+ (JSC::JSParser::popLabel):
+ (JSC::JSParser::hasLabel):
+ (JSC::JSParser::DepthManager::DepthManager):
+ (JSC::JSParser::DepthManager::~DepthManager):
+ (JSC::JSParser::Scope::Scope):
+ (JSC::JSParser::Scope::startSwitch):
+ (JSC::JSParser::Scope::endSwitch):
+ (JSC::JSParser::Scope::startLoop):
+ (JSC::JSParser::Scope::endLoop):
+ (JSC::JSParser::Scope::inLoop):
+ (JSC::JSParser::Scope::breakIsValid):
+ (JSC::JSParser::Scope::pushLabel):
+ (JSC::JSParser::Scope::popLabel):
+ (JSC::JSParser::Scope::hasLabel):
+ (JSC::JSParser::Scope::isFunction):
+ (JSC::JSParser::Scope::declareVariable):
+ (JSC::JSParser::Scope::declareWrite):
+ (JSC::JSParser::Scope::deleteProperty):
+ (JSC::JSParser::Scope::declareParameter):
+ (JSC::JSParser::Scope::setNeedsFullActivation):
+ (JSC::JSParser::Scope::collectFreeVariables):
+ (JSC::JSParser::Scope::getUncapturedWrittenVariables):
+ (JSC::JSParser::Scope::getDeletedVariables):
+ (JSC::JSParser::Scope::setStrictMode):
+ (JSC::JSParser::Scope::strictMode):
+ (JSC::JSParser::Scope::isValidStrictMode):
+ (JSC::JSParser::pushScope):
+ (JSC::JSParser::popScope):
+ (JSC::JSParser::declareVariable):
+ (JSC::JSParser::declareWrite):
+ (JSC::JSParser::deleteProperty):
+ (JSC::jsParse):
+ (JSC::JSParser::JSParser):
+ (JSC::JSParser::parseProgram):
+ (JSC::JSParser::parseSourceElements):
+ (JSC::JSParser::parseDoWhileStatement):
+ (JSC::JSParser::parseWhileStatement):
+ (JSC::JSParser::parseVarDeclarationList):
+ (JSC::JSParser::parseConstDeclarationList):
+ (JSC::JSParser::parseForStatement):
+ (JSC::JSParser::parseBreakStatement):
+ (JSC::JSParser::parseContinueStatement):
+ (JSC::JSParser::parseReturnStatement):
+ (JSC::JSParser::parseWithStatement):
+ (JSC::JSParser::parseSwitchStatement):
+ (JSC::JSParser::parseSwitchClauses):
+ (JSC::JSParser::parseSwitchDefaultClause):
+ (JSC::JSParser::parseTryStatement):
+ (JSC::JSParser::parseBlockStatement):
+ (JSC::JSParser::parseStatement):
+ (JSC::JSParser::parseFormalParameters):
+ (JSC::JSParser::parseFunctionBody):
+ (JSC::JSParser::parseFunctionInfo):
+ (JSC::JSParser::parseFunctionDeclaration):
+ (JSC::JSParser::parseExpressionOrLabelStatement):
+ (JSC::JSParser::parseIfStatement):
+ (JSC::JSParser::parseExpression):
+ (JSC::JSParser::parseAssignmentExpression):
+ (JSC::JSParser::parseConditionalExpression):
+ (JSC::JSParser::parseBinaryExpression):
+ (JSC::JSParser::parseStrictObjectLiteral):
+ (JSC::JSParser::parsePrimaryExpression):
+ (JSC::JSParser::parseMemberExpression):
+ (JSC::JSParser::parseUnaryExpression):
+ * parser/JSParser.h:
+ * parser/Lexer.cpp:
+ (JSC::Lexer::parseString):
+ (JSC::Lexer::lex):
+ * parser/Lexer.h:
+ (JSC::Lexer::isReparsing):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::isStrictMode):
+ * parser/Parser.cpp:
+ (JSC::Parser::parse):
+ * parser/Parser.h:
+ (JSC::Parser::parse):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::SyntaxChecker):
+ (JSC::SyntaxChecker::makeFunctionCallNode):
+ (JSC::SyntaxChecker::appendToComma):
+ (JSC::SyntaxChecker::createCommaExpr):
+ (JSC::SyntaxChecker::makeAssignNode):
+ (JSC::SyntaxChecker::makePrefixNode):
+ (JSC::SyntaxChecker::makePostfixNode):
+ (JSC::SyntaxChecker::makeTypeOfNode):
+ (JSC::SyntaxChecker::makeDeleteNode):
+ (JSC::SyntaxChecker::makeNegateNode):
+ (JSC::SyntaxChecker::makeBitwiseNotNode):
+ (JSC::SyntaxChecker::createLogicalNot):
+ (JSC::SyntaxChecker::createUnaryPlus):
+ (JSC::SyntaxChecker::createVoid):
+ (JSC::SyntaxChecker::thisExpr):
+ (JSC::SyntaxChecker::createResolve):
+ (JSC::SyntaxChecker::createObjectLiteral):
+ (JSC::SyntaxChecker::createArray):
+ (JSC::SyntaxChecker::createNumberExpr):
+ (JSC::SyntaxChecker::createString):
+ (JSC::SyntaxChecker::createBoolean):
+ (JSC::SyntaxChecker::createNull):
+ (JSC::SyntaxChecker::createBracketAccess):
+ (JSC::SyntaxChecker::createDotAccess):
+ (JSC::SyntaxChecker::createRegex):
+ (JSC::SyntaxChecker::createNewExpr):
+ (JSC::SyntaxChecker::createConditionalExpr):
+ (JSC::SyntaxChecker::createAssignResolve):
+ (JSC::SyntaxChecker::createFunctionExpr):
+ (JSC::SyntaxChecker::createFunctionBody):
+ (JSC::SyntaxChecker::appendBinaryExpressionInfo):
+ (JSC::SyntaxChecker::operatorStackPop):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::createStrictModeCallerIfNecessary):
+ (JSC::Arguments::createStrictModeCalleeIfNecessary):
+ (JSC::Arguments::getOwnPropertySlot):
+ (JSC::Arguments::getOwnPropertyDescriptor):
+ (JSC::Arguments::put):
+ (JSC::Arguments::deleteProperty):
+ * runtime/Arguments.h:
+ (JSC::Arguments::Arguments):
+ * runtime/CommonIdentifiers.cpp:
+ (JSC::CommonIdentifiers::CommonIdentifiers):
+ * runtime/CommonIdentifiers.h:
+ * runtime/Error.cpp:
+ (JSC::StrictModeTypeErrorFunction::StrictModeTypeErrorFunction):
+ (JSC::StrictModeTypeErrorFunction::constructThrowTypeError):
+ (JSC::StrictModeTypeErrorFunction::getConstructData):
+ (JSC::StrictModeTypeErrorFunction::callThrowTypeError):
+ (JSC::StrictModeTypeErrorFunction::getCallData):
+ (JSC::createTypeErrorFunction):
+ * runtime/Error.h:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::checkSyntax):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ (JSC::FunctionExecutable::reparseExceptionInfo):
+ (JSC::EvalExecutable::reparseExceptionInfo):
+ (JSC::FunctionExecutable::fromGlobalCode):
+ (JSC::ProgramExecutable::reparseExceptionInfo):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::ScriptExecutable::isStrictMode):
+ (JSC::EvalExecutable::create):
+ (JSC::FunctionExecutable::create):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::toStrictThisObject):
+ * runtime/JSActivation.h:
+ * runtime/JSFunction.cpp:
+ (JSC::createDescriptorForThrowingProperty):
+ (JSC::JSFunction::getOwnPropertySlot):
+ (JSC::JSFunction::getOwnPropertyDescriptor):
+ (JSC::JSFunction::put):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::internalFunctionStructure):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put):
+ (JSC::JSObject::toStrictThisObject):
+ (JSC::throwTypeError):
+ * runtime/JSObject.h:
+ (JSC::JSObject::isStrictModeFunction):
+ (JSC::JSObject::putDirectInternal):
+ (JSC::JSObject::putDirect):
+ (JSC::JSValue::putDirect):
+ (JSC::JSValue::toStrictThisObject):
+ * runtime/JSStaticScopeObject.cpp:
+ (JSC::JSStaticScopeObject::toStrictThisObject):
+ * runtime/JSStaticScopeObject.h:
+ * runtime/JSValue.h:
+ * runtime/JSZombie.h:
+ (JSC::JSZombie::toStrictThisObject):
+ * runtime/PutPropertySlot.h:
+ (JSC::PutPropertySlot::PutPropertySlot):
+ (JSC::PutPropertySlot::isStrictMode):
+ * runtime/StrictEvalActivation.cpp: Added.
+ (JSC::StrictEvalActivation::StrictEvalActivation):
+ (JSC::StrictEvalActivation::deleteProperty):
+ (JSC::StrictEvalActivation::toThisObject):
+ (JSC::StrictEvalActivation::toStrictThisObject):
+ * runtime/StrictEvalActivation.h: Added.
+
+2010-10-10 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed.
+
+ Windows build fix after r69472.
+
+ * wtf/text/StringHash.h:
+ (WTF::CaseFoldingHash::hash):
+
+2010-10-10 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Use WTF::StringHasher in WTF::CaseFoldingHash
+ https://bugs.webkit.org/show_bug.cgi?id=46523
+
+ * wtf/text/StringHash.h:
+ (WTF::CaseFoldingHash::foldCase):
+ (WTF::CaseFoldingHash::hash):
+
+2010-10-09 Pratik Solanki <psolanki@apple.com>
+
+ Reviewed by Xan Lopez.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47445
+ Remove unused function WTFThreadData::initializeIdentifierTable()
+
+ * wtf/WTFThreadData.h:
+
+2010-10-08 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Added check to start of subexpression being positive before using
+ subexpression in replacement.
+ https://bugs.webkit.org/show_bug.cgi?id=47324
+
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferencesSlow):
+
+2010-10-08 Chris Evans <cevans@google.com>
+
+ Reviewed by David Levin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47393
+
+ Use unsigned consistently to check for max StringImpl length.
+ Add a few integer overflow checks.
+ Uses the existing paradigm of CRASH() when we can't reasonably handle a crazily large request.
+
+ * wtf/text/WTFString.cpp:
+ * wtf/text/StringImpl.h:
+ * wtf/text/StringImpl.cpp:
+ Better use of size_t vs. unsigned; check for integer overflows.
+
+2010-10-07 David Goodwin <david_goodwin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ ARM JIT generates undefined operations due to partially uninitialized ShiftTypeAndAmount
+ https://bugs.webkit.org/show_bug.cgi?id=47356
+
+ * assembler/ARMv7Assembler.h:
+
+2010-10-06 Chris Evans <cevans@google.com>
+
+ Reviewed by David Levin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47248
+
+ Use size_t consistently in CString, to prevent theoretical trouble
+ with > 4GB strings on 64-bit platforms.
+
+ * wtf/text/CString.h:
+ * wtf/text/CString.cpp:
+ Use size_t for string lengths.
+ * wtf/MD5.cpp:
+ (WTF::expectMD5): use suitable format string + cast for size_t.
+ * JavaScriptCore.exp:
+ Update symbol name.
+
+2010-10-06 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Start cleaning up Arguments.h
+ https://bugs.webkit.org/show_bug.cgi?id=47304
+
+ * wtf/TypeTraits.h:
+ * wtf/TypeTraits.cpp:
+ Add RemoveReference type trait.
+
+2010-10-06 Rafael Antognolli <antognolli@profusion.mobi>
+
+ Unreviewed build fix.
+
+ [EFL] Build fix for glib support.
+ https://bugs.webkit.org/show_bug.cgi?id=47221
+
+ If compiling with GLib support enabled, we also need to link wtf against
+ glib library.
+
+ * wtf/CMakeListsEfl.txt:
+
+2010-10-05 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Gavin Barraclough.
+
+ [BREWMP] Port ExecutableAllocator::cacheFlush to enable ARM JIT
+ https://bugs.webkit.org/show_bug.cgi?id=47117
+
+ Use IMemCache1 to flush data cache and invalidate instruction cache.
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
+2010-10-05 Leandro Pereira <leandro@profusion.mobi>
+
+ Unreviewed. Build fix.
+
+ Moved "jsc" directory to "shell", so that the name does not clash with the
+ JavaScriptCore shell in some build systems.
+ http://webkit.org/b/47049
+
+ * CMakeLists.txt: Changed reference from "jsc" to "shell".
+ * jsc: Removed.
+ * jsc/CMakeLists.txt: Removed.
+ * jsc/CMakeListsEfl.txt: Removed.
+ * shell: Copied from JavaScriptCore/jsc.
+
+2010-10-05 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Use PlatformRefPtr in randomNumber
+ https://bugs.webkit.org/show_bug.cgi?id=46989
+
+ Use PlatformRefPtr to free memory automatically.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2010-10-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ REGRESSION(r68338): JavaScript error on PowerPC only (crashes on Interpreter built for x86_64)
+ https://bugs.webkit.org/show_bug.cgi?id=46690
+
+ Use the correct register value when initialising the arguments
+ object in the interpreter. This is covered by existing tests.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-10-04 David Goodwin <david_goodwin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ ARMv7 JIT should take advantage of 2-byte branches to reduce code size
+ https://bugs.webkit.org/show_bug.cgi?id=47007
+
+ * assembler/ARMv7Assembler.cpp:
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::computeJumpType):
+ (JSC::ARMv7Assembler::link):
+ (JSC::ARMv7Assembler::canBeJumpT2):
+ (JSC::ARMv7Assembler::canBeJumpT4):
+ (JSC::ARMv7Assembler::linkBX):
+ (JSC::ARMv7Assembler::linkJumpT4):
+ (JSC::ARMv7Assembler::linkJumpT2):
+ (JSC::ARMv7Assembler::linkJumpAbsolute):
+
+2010-10-04 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Antonio Gomes.
+
+ [EFL] Use fast malloc for WebKit EFL
+ https://bugs.webkit.org/show_bug.cgi?id=46691
+
+ Use fast malloc for WebKit EFL because the fast malloc is to allocate
+ memory quickly.
+
+ * wtf/CMakeListsEfl.txt:
+
+2010-10-04 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Lazily create activation objects
+ https://bugs.webkit.org/show_bug.cgi?id=47107
+
+ Make it possible to lazily create the activation object
+ for a function that needs one. This allows us to reduce
+ the overhead of entering a function that may require
+ an activation in some cases, but not always.
+
+ This does make exception handling a little more complex as
+ it's now necessary to verify that a callframes activation
+ has been created, and create it if not, in all of the
+ paths used in exception handling.
+
+ We also need to add logic to check for the existence of
+ the activation in the scoped_var opcodes, as well as
+ op_ret, op_ret_object_or_this and op_tearoff_activation
+ so that we can avoid creating an activation unnecesarily
+ on function exit.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
+ (JSC::CodeBlock::createActivation):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::setActivationRegister):
+ (JSC::CodeBlock::activationRegister):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitNewFunctionInternal):
+ (JSC::BytecodeGenerator::emitNewFunctionExpression):
+ (JSC::BytecodeGenerator::createActivationIfNecessary):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobalDynamic):
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_end):
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_tear_off_activation):
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::emit_op_create_activation):
+ (JSC::JIT::emit_op_resolve_global_dynamic):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_tear_off_activation):
+ (JSC::JIT::emit_op_create_activation):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2010-10-04 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ Remove ENABLE_SANDBOX
+ https://bugs.webkit.org/show_bug.cgi?id=47032
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-10-01 Pratik Solanki <psolanki@apple.com>
+
+ Reviewed by Geoffrey Garen.
+ Specify ALWAYS_INLINE at function declaration not function definition
+ https://bugs.webkit.org/show_bug.cgi?id=46960
+
+ For functions defined with ALWAYS_INLINE, add the attribute to the declaration as well.
+
+ * bytecompiler/BytecodeGenerator.h:
+ * wtf/FastMalloc.cpp:
+
+2010-10-01 Kwang Yul Seo <skyul@company100.net>
+
+ Unreviewed.
+
+ [BREWMP] Change Collector BLOCK_SIZE to 64KB
+ https://bugs.webkit.org/show_bug.cgi?id=46436
+
+ Lower BLOCK_SIZE to 64KB because Brew MP runs on low end devices.
+
+ * runtime/Collector.h:
+
+2010-10-01 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Stack overflow on symbian platform.
+ https://bugs.webkit.org/show_bug.cgi?id=40598
+
+ Move big allocation in arrayProtoFuncToString from stack to heap.
+ JSC::arrayProtoFuncToString function can be called recursivly and
+ 1K allocation on stack cahse stack overflow.
+ Can be useful for other platforms with limited stack size.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+
+2010-09-30 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Add a factory function which returns an instance wrapped in PlatformRefPtr.
+ https://bugs.webkit.org/show_bug.cgi?id=46373
+
+ A Brew MP instance has reference count 1 when it is created, so call adoptPlatformRef
+ to wrap the instance in PlatformRefPtr.
+
+ * wtf/brew/ShellBrew.h:
+ (WTF::createRefPtrInstance):
+
+2010-09-30 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ [BREWMP] Port PlatformRefPtr
+ https://bugs.webkit.org/show_bug.cgi?id=46370
+
+ Implement refPlatformPtr and derefPlatformPtr to use PlatformRefPtr in Brew MP.
+
+ * wtf/brew/RefPtrBrew.h: Added.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+
+2010-09-29 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Add additional checks to StringBuffer.
+ <rdar://problem/7756381>
+
+ * wtf/text/StringBuffer.h:
+ (WTF::StringBuffer::StringBuffer):
+ (WTF::StringBuffer::resize):
+
+2010-09-30 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Make 2D accelerated canvas rendering build on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=46007
+
+ Added ACCELERATED_2D_CANVAS to FeatureDefines
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-09-30 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] wxMSW build fix. Make sure we copy the compiler flags and remove exception handling from
+ the copy so as not to alter global settings.
+
+ * wscript:
+
+2010-09-30 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ The case-insensitivity backreference checking isn't working with YARR
+ Interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=46882
+
+ Add ignorecase checking to the Interpreter::tryConsumeBackReference() function.
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::Interpreter::tryConsumeBackReference):
+
+2010-09-30 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Andreas Kling.
+
+ [BREWMP] Leave initializeRandomNumberGenerator empty.
+ https://bugs.webkit.org/show_bug.cgi?id=46851
+
+ On Brew MP, AEECLSID_RANDOM initializes itself.
+
+ * wtf/RandomNumberSeed.h:
+ (WTF::initializeRandomNumberGenerator):
+
+2010-09-30 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Remove unnecessary cacheFlush calls from Thumb-2
+ https://bugs.webkit.org/show_bug.cgi?id=46702
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::relinkCall):
+ (JSC::ARMv7Assembler::repatchInt32):
+ (JSC::ARMv7Assembler::repatchPointer):
+
2010-09-29 Patrick Gansterer <paroga@webkit.org>
Unreviewed.
diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index 2ed3a8e..4c698ce 100644
--- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -33,6 +33,11 @@
ENABLE_LINK_PREFETCH = ;
+ENABLE_ACCELERATED_2D_CANVAS = $(ENABLE_ACCELERATED_2D_CANVAS_$(REAL_PLATFORM_NAME));
+ENABLE_ACCELERATED_2D_CANVAS_macosx = $(ENABLE_ACCELERATED_2D_CANVAS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+ENABLE_ACCELERATED_2D_CANVAS_macosx_1060 = ;
+ENABLE_ACCELERATED_2D_CANVAS_macosx_1070 = ;
+
ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(REAL_PLATFORM_NAME));
ENABLE_3D_CANVAS_macosx = $(ENABLE_3D_CANVAS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ENABLE_3D_CANVAS_macosx_1060 = ENABLE_3D_CANVAS;
@@ -88,9 +93,6 @@ ENABLE_PROGRESS_TAG = ENABLE_PROGRESS_TAG;
ENABLE_RUBY = $(ENABLE_RUBY_$(REAL_PLATFORM_NAME));
ENABLE_RUBY_macosx = ENABLE_RUBY;
-ENABLE_SANDBOX = $(ENABLE_SANDBOX_$(REAL_PLATFORM_NAME));
-ENABLE_SANDBOX_macosx = ENABLE_SANDBOX;
-
ENABLE_SHARED_WORKERS = $(ENABLE_SHARED_WORKERS_$(REAL_PLATFORM_NAME));
ENABLE_SHARED_WORKERS_macosx = ENABLE_SHARED_WORKERS;
@@ -119,4 +121,4 @@ ENABLE_XHTMLMP = ;
ENABLE_XPATH = ENABLE_XPATH;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_SYSTEM) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_SYSTEM) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index f688ea8..35ae251 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 = 10;
+MINOR_VERSION = 11;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 88d1761..c507f5d 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -388,8 +388,8 @@ javascriptcore_sources += \
JavaScriptCore/runtime/ScopeChainMark.h \
JavaScriptCore/runtime/SmallStrings.cpp \
JavaScriptCore/runtime/SmallStrings.h \
- JavaScriptCore/runtime/StringBuilder.h \
- JavaScriptCore/runtime/StringConcatenate.h \
+ JavaScriptCore/runtime/StrictEvalActivation.cpp \
+ JavaScriptCore/runtime/StrictEvalActivation.h \
JavaScriptCore/runtime/StringConstructor.cpp \
JavaScriptCore/runtime/StringConstructor.h \
JavaScriptCore/runtime/StringObject.cpp \
@@ -409,6 +409,8 @@ javascriptcore_sources += \
JavaScriptCore/runtime/Tracing.h \
JavaScriptCore/runtime/UString.cpp \
JavaScriptCore/runtime/UString.h \
+ JavaScriptCore/runtime/UStringBuilder.h \
+ JavaScriptCore/runtime/UStringConcatenate.h \
JavaScriptCore/runtime/WeakGCMap.h \
JavaScriptCore/runtime/WeakGCPtr.h \
JavaScriptCore/runtime/WeakRandom.h \
@@ -428,6 +430,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/DateMath.cpp \
JavaScriptCore/wtf/DateMath.h \
JavaScriptCore/wtf/DecimalNumber.h \
+ JavaScriptCore/wtf/DecimalNumber.cpp \
JavaScriptCore/wtf/Deque.h \
JavaScriptCore/wtf/DisallowCType.h \
JavaScriptCore/wtf/dtoa.cpp \
@@ -466,6 +469,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/NonCopyingSort.h \
JavaScriptCore/wtf/Noncopyable.h \
JavaScriptCore/wtf/NotFound.h \
+ JavaScriptCore/wtf/NullPtr.h \
JavaScriptCore/wtf/OwnArrayPtr.h \
JavaScriptCore/wtf/OwnFastMallocPtr.h \
JavaScriptCore/wtf/OwnArrayPtrCommon.h \
@@ -493,7 +497,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/StaticConstructors.h \
JavaScriptCore/wtf/StdLibExtras.h \
JavaScriptCore/wtf/StringExtras.h \
- JavaScriptCore/wtf/StringHashFunctions.h \
+ JavaScriptCore/wtf/StringHasher.h \
JavaScriptCore/wtf/TCPackedCache.h \
JavaScriptCore/wtf/TCPageMap.h \
JavaScriptCore/wtf/TCSpinLock.h \
@@ -506,6 +510,9 @@ javascriptcore_sources += \
JavaScriptCore/wtf/text/CString.cpp \
JavaScriptCore/wtf/text/CString.h \
JavaScriptCore/wtf/text/StringBuffer.h \
+ JavaScriptCore/wtf/text/StringBuilder.cpp \
+ JavaScriptCore/wtf/text/StringBuilder.h \
+ JavaScriptCore/wtf/text/StringConcatenate.h \
JavaScriptCore/wtf/text/StringHash.h \
JavaScriptCore/wtf/text/StringImplBase.h \
JavaScriptCore/wtf/text/StringImpl.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index ff3d9b3..6ef8ead 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -132,6 +132,8 @@ __ZN3JSC12JSGlobalData14sharedInstanceEv
__ZN3JSC12JSGlobalData15dumpRegExpTraceEv
__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
__ZN3JSC12JSGlobalDataD1Ev
+__ZN3JSC12RegExpObject4infoE
+__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEENS4_INS_6RegExpEEE
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
@@ -150,7 +152,6 @@ __ZN3JSC13SamplingFlags4stopEv
__ZN3JSC13SamplingFlags5startEv
__ZN3JSC13SamplingFlags7s_flagsE
__ZN3JSC13StatementNode6setLocEii
-__ZN3JSC14heapStatisticsEPNS_12JSGlobalDataE
__ZN3JSC14JSGlobalObject10globalExecEv
__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
@@ -165,6 +166,7 @@ __ZN3JSC14SamplingThread4stopEv
__ZN3JSC14SamplingThread5startEj
__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
__ZN3JSC14TimeoutChecker5resetEv
+__ZN3JSC14heapStatisticsEPNS_12JSGlobalDataE
__ZN3JSC14throwTypeErrorEPNS_9ExecStateE
__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE
@@ -239,6 +241,8 @@ __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
__ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
__ZN3JSC6JSLock9lockCountEv
__ZN3JSC6JSLockC1EPNS_9ExecStateE
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC6RegExpD1Ev
__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
__ZN3JSC7JSArray15setSubclassDataEPv
__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
@@ -372,6 +376,11 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
+__ZN3WTF13StringBuilder11reifyStringEv
+__ZN3WTF13StringBuilder11shrinkToFitEv
+__ZN3WTF13StringBuilder6appendEPKcj
+__ZN3WTF13StringBuilder6appendEPKtj
+__ZN3WTF13StringBuilder6resizeEj
__ZN3WTF13WTFThreadData10staticDataE
__ZN3WTF13WTFThreadDataC1Ev
__ZN3WTF13WTFThreadDataD1Ev
@@ -458,7 +467,7 @@ __ZN3WTF6strtodEPKcPPc
__ZN3WTF7CString11mutableDataEv
__ZN3WTF7CString16newUninitializedEmRPc
__ZN3WTF7CStringC1EPKc
-__ZN3WTF7CStringC1EPKcj
+__ZN3WTF7CStringC1EPKcm
__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
__ZN3WTF7xmlAtomE
@@ -484,8 +493,6 @@ __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_10JSFunctionE
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
-__ZN3JSC12RegExpObject4infoE
-__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEENS4_INS_6RegExpEEE
__ZNK3JSC14JSGlobalObject14isDynamicScopeERb
__ZNK3JSC16InternalFunction9classInfoEv
__ZNK3JSC16JSVariableObject16isVariableObjectEv
@@ -516,8 +523,6 @@ __ZNK3JSC6JSCell9getStringEPNS_9ExecStateE
__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
__ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
-__ZN3JSC6RegExpD1Ev
__ZNK3JSC7ArgList8getSliceEiRS0_
__ZNK3JSC7JSArray12subclassDataEv
__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
@@ -531,6 +536,7 @@ __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
+__ZNK3JSC8JSObject18toStrictThisObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
@@ -539,7 +545,12 @@ __ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3JSC9HashTable11deleteTableEv
+__ZN3WTF11dtoaRoundSFEPcdiRbRiRj
+__ZN3WTF11dtoaRoundDPEPcdiRbRiRj
+__ZN3WTF4dtoaEPcdRbRiRj
__ZNK3WTF12AtomicString5lowerEv
+__ZNK3WTF13DecimalNumber15toStringDecimalEPtj
+__ZNK3WTF13DecimalNumber28bufferLengthForStringDecimalEv
__ZNK3WTF6String11toIntStrictEPbi
__ZNK3WTF6String12toUIntStrictEPbi
__ZNK3WTF6String13toInt64StrictEPbi
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index 462960d..6252d07 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -346,6 +346,8 @@
'runtime/Tracing.h',
'runtime/UString.cpp',
'runtime/UString.h',
+ 'runtime/UStringBuilder.h',
+ 'runtime/UStringConcatenate.h',
'runtime/WeakRandom.h',
'wtf/AlwaysInline.h',
'wtf/ASCIICType.h',
@@ -363,6 +365,7 @@
'wtf/CurrentTime.h',
'wtf/DateMath.cpp',
'wtf/DateMath.h',
+ 'wtf/DecimalNumber.cpp',
'wtf/Deque.h',
'wtf/DisallowCType.h',
'wtf/dtoa.cpp',
@@ -422,7 +425,7 @@
'wtf/StaticConstructors.h',
'wtf/StdLibExtras.h',
'wtf/StringExtras.h',
- 'wtf/StringHashFunctions.h',
+ 'wtf/StringHasher.h',
'wtf/TCPackedCache.h',
'wtf/qt/MainThreadQt.cpp',
'wtf/qt/StringQt.cpp',
@@ -450,6 +453,10 @@
'wtf/text/AtomicStringImpl.h',
'wtf/text/CString.cpp',
'wtf/text/CString.h',
+ 'wtf/text/StringBuffer.h',
+ 'wtf/text/StringBuilder.cpp',
+ 'wtf/text/StringBuilder.h',
+ 'wtf/text/StringConcatenate.h',
'wtf/text/StringHash.h',
'wtf/text/StringImpl.cpp',
'wtf/text/StringImpl.h',
diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index 57b1ce8..847576d 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -54,6 +54,12 @@ win32-*: DEFINES += _HAS_TR1=0
DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
+# CONFIG += text_breaking_with_icu
+
+contains (CONFIG, text_breaking_with_icu) {
+ DEFINES += WTF_USE_QT_ICU_TEXT_BREAKING=1
+}
+
wince* {
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat
INCLUDEPATH += $$PWD/../JavaScriptCore/os-win32
diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro
index f463f41..f83bf4c 100644
--- a/JavaScriptCore/JavaScriptCore.pro
+++ b/JavaScriptCore/JavaScriptCore.pro
@@ -197,6 +197,7 @@ SOURCES += \
runtime/RopeImpl.cpp \
runtime/ScopeChain.cpp \
runtime/SmallStrings.cpp \
+ runtime/StrictEvalActivation.cpp \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index ba564f0..779b0bc 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -41,7 +41,6 @@ EXPORTS
??8JSC@@YA_NABVUString@0@0@Z
??8WTF@@YA_NABVCString@0@0@Z
?NaN@JSC@@3NB
- ?utf8@UString@JSC@@QBE?AVCString@WTF@@_N@Z
?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PBD@Z
?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z
?addBytes@MD5@WTF@@QAEXPBEI@Z
@@ -53,9 +52,12 @@ EXPORTS
?allocate@Heap@JSC@@QAEPAXI@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
?allocateStack@MarkStack@JSC@@CAPAXI@Z
+ ?append@StringBuilder@WTF@@QAEXPBDI@Z
+ ?append@StringBuilder@WTF@@QAEXPB_WI@Z
?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ
?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?broadcast@ThreadCondition@WTF@@QAEXXZ
+ ?bufferLengthForStringDecimal@DecimalNumber@WTF@@QBEIXZ
?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ
?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z
?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
@@ -130,6 +132,7 @@ EXPORTS
?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXI@Z
?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
+ ?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
?empty@StringImpl@WTF@@SAPAV12@XZ
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
@@ -149,10 +152,6 @@ EXPORTS
?free@WeakGCHandlePool@JSC@@QAEXPAVWeakGCHandle@2@@Z
?from@Identifier@JSC@@SA?AV12@PAVExecState@2@H@Z
?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z
- ?number@UString@JSC@@SA?AV12@H@Z
- ?number@UString@JSC@@SA?AV12@I@Z
- ?number@UString@JSC@@SA?AV12@N@Z
- ?numberToString@WTF@@YAINQA_W@Z
?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z
?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ
?get@Structure@JSC@@QAEIPBVStringImpl@WTF@@AAIAAPAVJSCell@2@@Z
@@ -193,7 +192,6 @@ EXPORTS
?hasTransition@Structure@JSC@@QAE_NPAVStringImpl@WTF@@I@Z
?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
?increment@RefCountedLeakCounter@WTF@@QAEXXZ
- ?info@RegExpObject@JSC@@2UClassInfo@2@B
?init@AtomicString@WTF@@SAXXZ
?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z
?initializeMainThread@WTF@@YAXXZ
@@ -230,6 +228,10 @@ EXPORTS
?name@JSFunction@JSC@@QAEABVUString@2@PAVExecState@2@@Z
?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z
?nonInlineNaN@JSC@@YANXZ
+ ?number@UString@JSC@@SA?AV12@H@Z
+ ?number@UString@JSC@@SA?AV12@I@Z
+ ?number@UString@JSC@@SA?AV12@N@Z
+ ?numberToString@WTF@@YAINQA_W@Z
?objectCount@Heap@JSC@@QBEIXZ
?objectProtoFuncToString@JSC@@YI_JPAVExecState@1@@Z
?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z
@@ -257,10 +259,12 @@ EXPORTS
?randomNumber@WTF@@YANXZ
?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z
?recordExtraCost@Heap@JSC@@AAEXI@Z
+ ?reifyString@StringBuilder@WTF@@AAEXXZ
?releaseStack@MarkStack@JSC@@CAXPAXI@Z
?reset@ParserArena@JSC@@QAEXXZ
?reset@TimeoutChecker@JSC@@QAEXXZ
?resetDateCache@JSGlobalData@JSC@@QAEXXZ
+ ?resize@StringBuilder@WTF@@QAEXI@Z
?resolveRope@JSString@JSC@@ABEXPAVExecState@2@@Z
?restoreAll@Profile@JSC@@QAEXXZ
?retrieveCaller@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVJSFunction@2@@Z
@@ -280,6 +284,7 @@ EXPORTS
?setUpStaticFunctionSlot@JSC@@YAXPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@ABVIdentifier@1@AAVPropertySlot@1@@Z
?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
+ ?shrinkToFit@StringBuilder@WTF@@QAEXXZ
?signal@ThreadCondition@WTF@@QAEXXZ
?size@Heap@JSC@@QBEIXZ
?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z
@@ -315,6 +320,8 @@ EXPORTS
?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
?toPrimitive@JSCell@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
?toPrimitive@JSString@JSC@@EBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
+ ?toStrictThisObject@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@@Z
+ ?toStringDecimal@DecimalNumber@WTF@@QBEIPA_WI@Z
?toString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z
?toString@JSObject@JSC@@UBE?AVUString@2@PAVExecState@2@@Z
?toString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z
@@ -325,6 +332,7 @@ EXPORTS
?toUInt32@Identifier@JSC@@SAIABVUString@2@AA_N@Z
?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z
?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z
+ ?tryFastRealloc@WTF@@YA?AUTryMallocReturnValue@1@PAXI@Z
?tryLock@Mutex@WTF@@QAE_NXZ
?type@DebuggerCallFrame@JSC@@QBE?AW4Type@12@XZ
?unlock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z
@@ -332,6 +340,7 @@ EXPORTS
?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
+ ?utf8@UString@JSC@@QBE?AVCString@WTF@@_N@Z
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
?writable@PropertyDescriptor@JSC@@QBE_NXZ
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 83d34e3..4823286 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -1173,6 +1173,14 @@
>
</File>
<File
+ RelativePath="..\..\runtime\StrictEvalActivation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\StrictEvalActivation.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\StringConstructor.cpp"
>
</File>
@@ -1245,6 +1253,14 @@
>
</File>
<File
+ RelativePath="..\..\runtime\UStringBuilder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\UStringConcatenate.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\UStringImpl.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
index c92196e..6929c8a 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
@@ -19,7 +19,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\AtomicString.cpp&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\StringImpl.cpp&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\WTFString.cpp&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCPreBuildEventTool"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
index 098ff08..d1e5d46 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
@@ -21,6 +21,32 @@ all:
xcopy /y /d "..\..\API\JSRetainPtr.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\OpaqueJSString.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\WebKitAvailability.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
+
+ -mkdir 2>NUL "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+
+ xcopy /y /d "..\..\wtf\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\text\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\unicode\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\unicode\icu\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\parser\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\runtime\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\bytecode\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\interpreter\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\assembler\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\jit\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\debugger\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\profiler\*.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\create_hash_table" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\pcre\pcre.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\text\AtomicString.cpp" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\text\StringBuilder.cpp" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\text\StringImpl.cpp" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ xcopy /y /d "..\..\wtf\text\WTFString.cpp" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+
+
+ -mkdir 2>NUL "$(WEBKITOUTPUTDIR)\bin\JavaScriptCore.resources"
+ xcopy /y /d "..\JavaScriptCore.resources\*" "$(WEBKITOUTPUTDIR)\bin\JavaScriptCore.resources"
+
-del "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore\stdbool.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore\stdint.h"
-del "$(WEBKITOUTPUTDIR)\buildfailed"
@@ -28,3 +54,5 @@ clean:
-del "$(WEBKITOUTPUTDIR)\buildfailed"
-del /s /q "$(WEBKITOUTPUTDIR)\include\JavaScriptCore\JavaScriptCore"
-del /s /q "$(WEBKITOUTPUTDIR)\obj\JavaScriptCore\DerivedSources"
+ -del /s /q "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore"
+ -del /s /q "$(WEBKITOUTPUTDIR)\bin\JavaScriptCore.resources"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 42a91eb..3a53070 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -309,6 +309,14 @@
>
</File>
<File
+ RelativePath="..\..\wtf\DecimalNumber.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\DecimalNumber.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\FastAllocBase.h"
>
</File>
@@ -609,6 +617,22 @@
>
</File>
<File
+ RelativePath="..\..\wtf\text\StringBuffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringBuilder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringBuilder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringConcatenate.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\text\StringHash.h"
>
</File>
@@ -620,6 +644,10 @@
RelativePath="..\..\wtf\text\StringImpl.h"
>
</File>
+ <File
+ RelativePath="..\..\wtf\text\TextPosition.h"
+ >
+ </File>
<File
RelativePath="..\..\wtf\text\WTFString.cpp"
>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
index 0f3e145..029a4b0 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
@@ -334,6 +334,10 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\include\private\JavaScriptCore\StringBuilder.cpp"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\include\private\JavaScriptCore\StringImpl.cpp"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 675d26d..d134a73 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -36,14 +36,18 @@
/* Begin PBXBuildFile section */
06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A20DAAD9C4003B174E /* MainThread.cpp */; };
06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A10DAAD9C4003B174E /* MainThreadMac.mm */; };
+ 081469491264378500DFF935 /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081469481264375E00DFF935 /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 088FA5B90EF76D4300578E6F /* RandomNumber.cpp */; };
088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 088FA5BA0EF76D4300578E6F /* RandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 08CABBA61265AB3900B206CE /* StringConcatenate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0896C29E1265AB0900B1CDD3 /* StringConcatenate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 08DDA5C11264631700751732 /* UStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DDA5BB12645F1D00751732 /* UStringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */; };
0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B330C260F38C62300692DE3 /* TypeTraits.cpp */; };
0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
+ 0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */; };
14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; };
@@ -182,7 +186,7 @@
5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
5D5D8AB60E0D0A7200F9C692 /* jsc in Copy Into Framework */ = {isa = PBXBuildFile; fileRef = 932F5BE10822A1C700736975 /* jsc */; };
5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
- 5D63E9AD10F2BD6E00FC8AE9 /* StringHashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 5D63E9AD10F2BD6E00FC8AE9 /* StringHasher.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D63E9AC10F2BD6E00FC8AE9 /* StringHasher.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D6A566B0F05995500266145 /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D6A566A0F05995500266145 /* Threading.cpp */; };
5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; };
6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -201,8 +205,9 @@
8626BECF11928E3900782FAB /* StringStatics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8626BECE11928E3900782FAB /* StringStatics.cpp */; };
8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8627E5E911F1281900A313B5 /* PageAllocation.cpp */; };
8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8627E5EA11F1281900A313B5 /* PageAllocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 862AF4B512239C7B0024E5B8 /* DecimalNumber.h */; };
+ 862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 862AF4B512239C7B0024E5B8 /* DecimalNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86438FC41265503E00E0DFCA /* StringBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86438FC31265503E00E0DFCA /* StringBuilder.cpp */; };
86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; };
86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; };
865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; };
@@ -217,13 +222,11 @@
868BFA18117CF19900B908B1 /* WTFString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA16117CF19900B908B1 /* WTFString.h */; settings = {ATTRIBUTES = (Private, ); }; };
868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
8690231512092D5C00630AF9 /* PageReservation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8690231412092D5C00630AF9 /* PageReservation.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; };
86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; };
- 86B6DA0212132B9A000D316F /* StringConcatenate.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B6DA0112132B9A000D316F /* StringConcatenate.h */; };
86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; };
86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AB7117E391E00DF5A90 /* RopeImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -275,6 +278,7 @@
932F5BEA0822A1C700736975 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
933040040E6A749400786E6A /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93303FE80E6A72B500786E6A /* SmallStrings.cpp */; };
+ 933F5CDC1269229B0049191E /* NullPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 933F5CDB126922690049191E /* NullPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 937013470CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp */; settings = {COMPILER_FLAGS = "-Wno-sign-compare"; }; };
93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E26BD308B1514100F85226 /* pcre_xclass.cpp */; };
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 952C63AC0E4777D600C13936 /* JSProfilerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -310,6 +314,8 @@
9714AF5F122F32070092D9F5 /* ParsedURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF58122F31F50092D9F5 /* ParsedURL.h */; };
9714AF60122F32070092D9F5 /* URLString.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF59122F31F50092D9F5 /* URLString.h */; };
971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 972A485F12661E0800F4514F /* URLCharacterTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 972A485D12661E0800F4514F /* URLCharacterTypes.cpp */; };
+ 972A48771266256F00F4514F /* URLEscape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 972A48741266256F00F4514F /* URLEscape.cpp */; };
A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1712B3A11C7B212007A5315 /* RegExpCache.cpp */; };
A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B4011C7B235007A5315 /* RegExpKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -318,6 +324,8 @@
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; };
+ A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */; };
A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386551118697B400540279 /* SpecializedThunkJIT.h */; };
A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7386552118697B400540279 /* ThunkGenerators.cpp */; };
A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -627,14 +635,19 @@
06D358A10DAAD9C4003B174E /* MainThreadMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MainThreadMac.mm; sourceTree = "<group>"; };
06D358A20DAAD9C4003B174E /* MainThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainThread.cpp; sourceTree = "<group>"; };
06D358A30DAAD9C4003B174E /* MainThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainThread.h; sourceTree = "<group>"; };
+ 081469481264375E00DFF935 /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuilder.h; path = text/StringBuilder.h; sourceTree = "<group>"; };
088FA5B90EF76D4300578E6F /* RandomNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomNumber.cpp; sourceTree = "<group>"; };
088FA5BA0EF76D4300578E6F /* RandomNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumber.h; sourceTree = "<group>"; };
+ 0896C29B1265AAF600B1CDD3 /* UStringConcatenate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringConcatenate.h; sourceTree = "<group>"; };
+ 0896C29E1265AB0900B1CDD3 /* StringConcatenate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringConcatenate.h; path = text/StringConcatenate.h; sourceTree = "<group>"; };
+ 08DDA5BB12645F1D00751732 /* UStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringBuilder.h; sourceTree = "<group>"; };
08E279E80EF83B10007DB523 /* RandomNumberSeed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumberSeed.h; sourceTree = "<group>"; };
0B330C260F38C62300692DE3 /* TypeTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeTraits.cpp; sourceTree = "<group>"; };
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnFastMallocPtr.h; sourceTree = "<group>"; };
0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadRefCounted.h; sourceTree = "<group>"; };
0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
+ 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecimalNumber.cpp; sourceTree = "<group>"; };
14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCPtr.h; sourceTree = "<group>"; };
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
@@ -741,7 +754,7 @@
5D53726E0E1C54880021E549 /* Tracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = "<group>"; };
5D53727D0E1C55EC0021E549 /* TracingDtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TracingDtrace.h; sourceTree = "<group>"; };
5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; };
- 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringHashFunctions.h; sourceTree = "<group>"; };
+ 5D63E9AC10F2BD6E00FC8AE9 /* StringHasher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringHasher.h; sourceTree = "<group>"; };
5D6A566A0F05995500266145 /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; };
5DA479650CFBCF56009328A0 /* TCPackedCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPackedCache.h; sourceTree = "<group>"; };
5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = "<group>"; };
@@ -803,6 +816,7 @@
8627E5EA11F1281900A313B5 /* PageAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageAllocation.h; sourceTree = "<group>"; };
862AF4B512239C7B0024E5B8 /* DecimalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecimalNumber.h; sourceTree = "<group>"; };
863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
+ 86438FC31265503E00E0DFCA /* StringBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringBuilder.cpp; path = text/StringBuilder.cpp; sourceTree = "<group>"; };
86565740115BE3DA00291F40 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = text/CString.cpp; sourceTree = "<group>"; };
86565741115BE3DA00291F40 /* CString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CString.h; path = text/CString.h; sourceTree = "<group>"; };
865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; };
@@ -820,13 +834,11 @@
868BFA16117CF19900B908B1 /* WTFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTFString.h; path = text/WTFString.h; sourceTree = "<group>"; };
868BFA5F117D048200B908B1 /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; };
8690231412092D5C00630AF9 /* PageReservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageReservation.h; sourceTree = "<group>"; };
- 8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; };
- 86B6DA0112132B9A000D316F /* StringConcatenate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringConcatenate.h; sourceTree = "<group>"; };
86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; };
86B99AB7117E391E00DF5A90 /* RopeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeImpl.h; sourceTree = "<group>"; };
86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; };
@@ -882,6 +894,7 @@
93303FEA0E6A72C000786E6A /* SmallStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallStrings.h; sourceTree = "<group>"; };
933A349A038AE7C6008635CE /* Identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Identifier.h; sourceTree = "<group>"; tabWidth = 8; };
933A349D038AE80F008635CE /* Identifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Identifier.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ 933F5CDB126922690049191E /* NullPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullPtr.h; sourceTree = "<group>"; };
935AF46909E9D9DB00ACD1D8 /* Forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Forward.h; sourceTree = "<group>"; };
935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedParam.h; sourceTree = "<group>"; };
937013470CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcre_ucp_searchfuncs.cpp; sourceTree = "<group>"; };
@@ -939,6 +952,11 @@
9714AF57122F31F50092D9F5 /* ParsedURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParsedURL.cpp; path = url/api/ParsedURL.cpp; sourceTree = "<group>"; };
9714AF58122F31F50092D9F5 /* ParsedURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParsedURL.h; path = url/api/ParsedURL.h; sourceTree = "<group>"; };
9714AF59122F31F50092D9F5 /* URLString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLString.h; path = url/api/URLString.h; sourceTree = "<group>"; };
+ 972A485D12661E0800F4514F /* URLCharacterTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = URLCharacterTypes.cpp; path = url/src/URLCharacterTypes.cpp; sourceTree = "<group>"; };
+ 972A485E12661E0800F4514F /* URLCharacterTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLCharacterTypes.h; path = url/src/URLCharacterTypes.h; sourceTree = "<group>"; };
+ 972A48741266256F00F4514F /* URLEscape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = URLEscape.cpp; path = url/src/URLEscape.cpp; sourceTree = "<group>"; };
+ 972A48751266256F00F4514F /* URLEscape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLEscape.h; path = url/src/URLEscape.h; sourceTree = "<group>"; };
+ 972A48761266256F00F4514F /* URLQueryCanonicalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLQueryCanonicalizer.h; path = url/src/URLQueryCanonicalizer.h; sourceTree = "<group>"; };
97F6903A1169DF7F00A6BB46 /* Terminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminator.h; sourceTree = "<group>"; };
A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
@@ -951,6 +969,8 @@
A72701B30DADE94900E548D7 /* ExceptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHelpers.h; sourceTree = "<group>"; };
A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; };
A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; };
+ A730B6101250068F009D25B1 /* StrictEvalActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrictEvalActivation.h; sourceTree = "<group>"; };
+ A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StrictEvalActivation.cpp; sourceTree = "<group>"; };
A7386551118697B400540279 /* SpecializedThunkJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecializedThunkJIT.h; sourceTree = "<group>"; };
A7386552118697B400540279 /* ThunkGenerators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThunkGenerators.cpp; sourceTree = "<group>"; };
A7386553118697B400540279 /* ThunkGenerators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerators.h; sourceTree = "<group>"; };
@@ -1470,6 +1490,7 @@
41359CF40FDD89CB00206180 /* DateMath.cpp */,
41359CF50FDD89CB00206180 /* DateMath.h */,
862AF4B512239C7B0024E5B8 /* DecimalNumber.h */,
+ 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */,
5186111D0CC824830081412B /* Deque.h */,
938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
651F6412039D5B5F0078395C /* dtoa.cpp */,
@@ -1501,6 +1522,7 @@
65E1A2F4122B880D00B26097 /* NonCopyingSort.h */,
9303F5690991190000AD71B8 /* Noncopyable.h */,
C0A2723F0E509F1E00E96E15 /* NotFound.h */,
+ 933F5CDB126922690049191E /* NullPtr.h */,
9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */,
BCFBE697122561D200309E9D /* OwnArrayPtrCommon.h */,
0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */,
@@ -1528,7 +1550,7 @@
868BFA5F117D048200B908B1 /* StaticConstructors.h */,
FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */,
E11D51750B2E798D0056C188 /* StringExtras.h */,
- 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */,
+ 5D63E9AC10F2BD6E00FC8AE9 /* StringHasher.h */,
5DA479650CFBCF56009328A0 /* TCPackedCache.h */,
6541BD6E08E80A17002CBEE7 /* TCPageMap.h */,
6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */,
@@ -1789,8 +1811,6 @@
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */,
93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
93303FEA0E6A72C000786E6A /* SmallStrings.h */,
- 8698B86810D44D9400D8D01B /* StringBuilder.h */,
- 86B6DA0112132B9A000D316F /* StringConcatenate.h */,
BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
BC18C3C10E16EE3300B34460 /* StringConstructor.h */,
BC18C3C20E16EE3300B34460 /* StringObject.cpp */,
@@ -1811,9 +1831,13 @@
5D53726E0E1C54880021E549 /* Tracing.h */,
F692A8850255597D01FF60F7 /* UString.cpp */,
F692A8860255597D01FF60F7 /* UString.h */,
+ 08DDA5BB12645F1D00751732 /* UStringBuilder.h */,
+ 0896C29B1265AAF600B1CDD3 /* UStringConcatenate.h */,
14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */,
1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
+ A730B6101250068F009D25B1 /* StrictEvalActivation.h */,
+ A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */,
);
path = runtime;
sourceTree = "<group>";
@@ -1828,6 +1852,9 @@
86565740115BE3DA00291F40 /* CString.cpp */,
86565741115BE3DA00291F40 /* CString.h */,
86B99AE1117E578100DF5A90 /* StringBuffer.h */,
+ 86438FC31265503E00E0DFCA /* StringBuilder.cpp */,
+ 081469481264375E00DFF935 /* StringBuilder.h */,
+ 0896C29E1265AB0900B1CDD3 /* StringConcatenate.h */,
868BFA05117CEFD100B908B1 /* StringHash.h */,
868BFA06117CEFD100B908B1 /* StringImpl.cpp */,
868BFA07117CEFD100B908B1 /* StringImpl.h */,
@@ -1944,8 +1971,13 @@
children = (
9714AF31122F27E70092D9F5 /* RawURLBuffer.h */,
9714AF32122F27E70092D9F5 /* URLBuffer.h */,
+ 972A485D12661E0800F4514F /* URLCharacterTypes.cpp */,
+ 972A485E12661E0800F4514F /* URLCharacterTypes.h */,
9714AF33122F27E70092D9F5 /* URLComponent.h */,
+ 972A48741266256F00F4514F /* URLEscape.cpp */,
+ 972A48751266256F00F4514F /* URLEscape.h */,
9714AF34122F27E70092D9F5 /* URLParser.h */,
+ 972A48761266256F00F4514F /* URLQueryCanonicalizer.h */,
9714AF35122F27E70092D9F5 /* URLSegments.cpp */,
9714AF36122F27E70092D9F5 /* URLSegments.h */,
);
@@ -2250,11 +2282,12 @@
868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */,
86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */,
- 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */,
+ 081469491264378500DFF935 /* StringBuilder.h in Headers */,
+ 08CABBA61265AB3900B206CE /* StringConcatenate.h in Headers */,
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
BC18C4670E16F5CD00B34460 /* StringExtras.h in Headers */,
868BFA0D117CEFD100B908B1 /* StringHash.h in Headers */,
- 5D63E9AD10F2BD6E00FC8AE9 /* StringHashFunctions.h in Headers */,
+ 5D63E9AD10F2BD6E00FC8AE9 /* StringHasher.h in Headers */,
868BFA0F117CEFD100B908B1 /* StringImpl.h in Headers */,
86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */,
BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
@@ -2286,6 +2319,7 @@
BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */,
BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */,
BC18C4760E16F5CD00B34460 /* UString.h in Headers */,
+ 08DDA5C11264631700751732 /* UStringBuilder.h in Headers */,
BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
BC18C4780E16F5CD00B34460 /* Vector.h in Headers */,
@@ -2302,7 +2336,6 @@
DD2724691208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */,
DDE82AD81209D955005C1756 /* GCHandle.h in Headers */,
86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */,
- 86B6DA0212132B9A000D316F /* StringConcatenate.h in Headers */,
862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */,
BCFBE696122560E800309E9D /* PassOwnArrayPtr.h in Headers */,
BCFBE698122561D200309E9D /* OwnArrayPtrCommon.h in Headers */,
@@ -2314,6 +2347,8 @@
9714AF5F122F32070092D9F5 /* ParsedURL.h in Headers */,
9714AF60122F32070092D9F5 /* URLString.h in Headers */,
90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
+ A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */,
+ 933F5CDC1269229B0049191E /* NullPtr.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2407,6 +2442,7 @@
isa = PBXProject;
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 2.4";
+ developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
@@ -2768,6 +2804,9 @@
9714AF46122F28850092D9F5 /* URLSegments.cpp in Sources */,
9714AF5E122F32070092D9F5 /* ParsedURL.cpp in Sources */,
90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */,
+ A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
+ 86438FC41265503E00E0DFCA /* StringBuilder.cpp in Sources */,
+ 0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2777,6 +2816,8 @@
files = (
932F5BDD0822A1C700736975 /* jsc.cpp in Sources */,
DDE82AD31209D955005C1756 /* GCHandle.cpp in Sources */,
+ 972A485F12661E0800F4514F /* URLCharacterTypes.cpp in Sources */,
+ 972A48771266256F00F4514F /* URLEscape.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/assembler/ARMv7Assembler.cpp b/JavaScriptCore/assembler/ARMv7Assembler.cpp
index 233a6f1..7aa1f10 100644
--- a/JavaScriptCore/assembler/ARMv7Assembler.cpp
+++ b/JavaScriptCore/assembler/ARMv7Assembler.cpp
@@ -31,7 +31,10 @@
namespace JSC {
-const int ARMv7Assembler::JumpSizes[] = { 0xffffffff, 2 * sizeof(uint16_t), 2 * sizeof(uint16_t), 5 * sizeof(uint16_t) };
+const int ARMv7Assembler::JumpSizes[] = { 0xffffffff, sizeof(uint16_t), sizeof(uint16_t),
+ 2 * sizeof(uint16_t), 2 * sizeof(uint16_t), 3 * sizeof(uint16_t), 5 * sizeof(uint16_t), 6 * sizeof(uint16_t) };
+const int ARMv7Assembler::JumpPaddingSizes[] = { 0, 5 * sizeof(uint16_t), 6 * sizeof(uint16_t),
+ 5 * sizeof(uint16_t), 6 * sizeof(uint16_t) };
}
diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h
index d960546..37b650b 100644
--- a/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -440,7 +440,7 @@ private:
};
struct {
unsigned type : 2;
- unsigned amount : 5;
+ unsigned amount : 6;
};
} m_u;
};
@@ -478,10 +478,11 @@ public:
ConditionInvalid
} Condition;
- enum JumpType { JumpNoCondition, JumpCondition, JumpFullSize };
- enum JumpLinkType { LinkInvalid, LinkShortJump, LinkConditionalShortJump, LinkLongJump, JumpTypeCount };
- static const int JumpSizes[JumpTypeCount];
- enum { JumpPaddingSize = 5 * sizeof(uint16_t) };
+ enum JumpType { JumpFixed, JumpNoCondition, JumpCondition, JumpNoConditionFixedSize, JumpConditionFixedSize, JumpTypeCount };
+ enum JumpLinkType { LinkInvalid, LinkJumpT1, LinkJumpT2, LinkJumpT3,
+ LinkJumpT4, LinkConditionalJumpT4, LinkBX, LinkConditionalBX, JumpLinkTypeCount };
+ static const int JumpSizes[JumpLinkTypeCount];
+ static const int JumpPaddingSizes[JumpTypeCount];
class LinkRecord {
public:
LinkRecord(intptr_t from, intptr_t to, JumpType type, Condition condition)
@@ -502,8 +503,8 @@ public:
private:
intptr_t m_from : 31;
intptr_t m_to : 31;
- JumpType m_type : 2;
- JumpLinkType m_linkType : 3;
+ JumpType m_type : 3;
+ JumpLinkType m_linkType : 4;
Condition m_condition : 16;
};
@@ -523,7 +524,7 @@ public:
, m_condition(ConditionInvalid)
, m_type(type)
{
- ASSERT(m_type != JumpCondition);
+ ASSERT(m_type == JumpFixed || m_type == JumpNoCondition || m_type == JumpNoConditionFixedSize);
}
JmpSrc(int offset, JumpType type, Condition condition)
@@ -531,7 +532,7 @@ public:
, m_condition(condition)
, m_type(type)
{
- ASSERT(m_type == JumpCondition || m_type == JumpFullSize);
+ ASSERT(m_type == JumpFixed || m_type == JumpCondition || m_type == JumpConditionFixedSize);
}
int m_offset;
@@ -628,6 +629,8 @@ private:
} OpcodeID;
typedef enum {
+ OP_B_T1 = 0xD000,
+ OP_B_T2 = 0xE000,
OP_AND_reg_T2 = 0xEA00,
OP_TST_reg_T2 = 0xEA10,
OP_ORR_reg_T2 = 0xEA40,
@@ -655,6 +658,7 @@ private:
OP_VCVT_FPIVFP = 0xEEB0,
OP_VMOV_IMM_T2 = 0xEEB0,
OP_VMRS = 0xEEB0,
+ OP_B_T3a = 0xF000,
OP_B_T4a = 0xF000,
OP_AND_imm_T1 = 0xF000,
OP_TST_imm = 0xF010,
@@ -707,6 +711,7 @@ private:
OP_VCVT_FPIVFPb = 0x0A40,
OP_VSUB_T2b = 0x0A40,
OP_NOP_T2b = 0x8000,
+ OP_B_T3b = 0x8000,
OP_B_T4b = 0x9000,
} OpcodeID2;
@@ -743,7 +748,7 @@ private:
| (ifThenElseConditionBit(condition, inst3if) << 2)
| (ifThenElseConditionBit(condition, inst4if) << 1)
| 1;
- ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+ ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
return (condition << 4) | mask;
}
uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if)
@@ -751,21 +756,20 @@ private:
int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
| (ifThenElseConditionBit(condition, inst3if) << 2)
| 2;
- ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+ ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
return (condition << 4) | mask;
}
uint8_t ifThenElse(Condition condition, bool inst2if)
{
int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
| 4;
- ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+ ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
return (condition << 4) | mask;
}
uint8_t ifThenElse(Condition condition)
{
int mask = 8;
- ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
return (condition << 4) | mask;
}
@@ -1662,7 +1666,7 @@ public:
return static_cast<int32_t*>(m_formatter.data())[location / sizeof(int32_t) - 1];
}
- int jumpSizeDelta(JumpLinkType jumpLinkType) { return JumpPaddingSize - JumpSizes[jumpLinkType]; }
+ int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JumpPaddingSizes[jumpType] - JumpSizes[jumpLinkType]; }
// Assembler admin methods:
@@ -1676,30 +1680,73 @@ public:
return a.from() < b.from();
}
- JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to)
+ bool canCompact(JumpType jumpType)
{
- if (record.type() >= JumpFullSize) {
- record.setLinkType(LinkLongJump);
- return LinkLongJump;
- }
+ // The following cannot be compacted:
+ // JumpFixed: represents custom jump sequence
+ // JumpNoConditionFixedSize: represents unconditional jump that must remain a fixed size
+ // JumpConditionFixedSize: represents conditional jump that must remain a fixed size
+ return (jumpType == JumpNoCondition) || (jumpType == JumpCondition);
+ }
+
+ JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to)
+ {
+ if (jumpType == JumpFixed)
+ return LinkInvalid;
+
+ // for patchable jump we must leave space for the longest code sequence
+ if (jumpType == JumpNoConditionFixedSize)
+ return LinkBX;
+ if (jumpType == JumpConditionFixedSize)
+ return LinkConditionalBX;
+
+ const int paddingSize = JumpPaddingSizes[jumpType];
bool mayTriggerErrata = false;
- const uint16_t* shortJumpLocation = reinterpret_cast<const uint16_t*>(from - (JumpPaddingSize - JumpSizes[LinkShortJump]));
- if (!canBeShortJump(shortJumpLocation, to, mayTriggerErrata)) {
- record.setLinkType(LinkLongJump);
- return LinkLongJump;
- }
- if (mayTriggerErrata) {
- record.setLinkType(LinkLongJump);
- return LinkLongJump;
- }
- if (record.type() == JumpCondition) {
- record.setLinkType(LinkConditionalShortJump);
- return LinkConditionalShortJump;
+
+ if (jumpType == JumpCondition) {
+ // 2-byte conditional T1
+ const uint16_t* jumpT1Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT1]));
+ if (canBeJumpT1(jumpT1Location, to))
+ return LinkJumpT1;
+ // 4-byte conditional T3
+ const uint16_t* jumpT3Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT3]));
+ if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) {
+ if (!mayTriggerErrata)
+ return LinkJumpT3;
+ }
+ // 4-byte conditional T4 with IT
+ const uint16_t* conditionalJumpT4Location =
+ reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkConditionalJumpT4]));
+ if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) {
+ if (!mayTriggerErrata)
+ return LinkConditionalJumpT4;
+ }
+ } else {
+ // 2-byte unconditional T2
+ const uint16_t* jumpT2Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT2]));
+ if (canBeJumpT2(jumpT2Location, to))
+ return LinkJumpT2;
+ // 4-byte unconditional T4
+ const uint16_t* jumpT4Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT4]));
+ if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) {
+ if (!mayTriggerErrata)
+ return LinkJumpT4;
+ }
+ // use long jump sequence
+ return LinkBX;
}
- record.setLinkType(LinkShortJump);
- return LinkShortJump;
+
+ ASSERT(jumpType == JumpCondition);
+ return LinkConditionalBX;
}
-
+
+ JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to)
+ {
+ JumpLinkType linkType = computeJumpType(record.type(), from, to);
+ record.setLinkType(linkType);
+ return linkType;
+ }
+
void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset)
{
int32_t ptr = regionStart / sizeof(int32_t);
@@ -1717,16 +1764,32 @@ public:
void link(LinkRecord& record, uint8_t* from, uint8_t* to)
{
- uint16_t* itttLocation;
- if (record.linkType() == LinkConditionalShortJump) {
- itttLocation = reinterpret_cast<uint16_t*>(from - JumpSizes[LinkConditionalShortJump] - 2);
- itttLocation[0] = ifThenElse(record.condition()) | OP_IT;
+ switch (record.linkType()) {
+ case LinkJumpT1:
+ linkJumpT1(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkJumpT2:
+ linkJumpT2(reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkJumpT3:
+ linkJumpT3(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkJumpT4:
+ linkJumpT4(reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkConditionalJumpT4:
+ linkConditionalJumpT4(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkConditionalBX:
+ linkConditionalBX(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ break;
+ case LinkBX:
+ linkBX(reinterpret_cast<uint16_t*>(from), to);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
}
- ASSERT(record.linkType() != LinkInvalid);
- if (record.linkType() != LinkLongJump)
- linkShortJump(reinterpret_cast<uint16_t*>(from), to);
- else
- linkLongJump(reinterpret_cast<uint16_t*>(from), to);
}
void* unlinkedCode() { return m_formatter.data(); }
@@ -1792,8 +1855,6 @@ public:
ASSERT(reinterpret_cast<intptr_t>(to) & 1);
setPointer(reinterpret_cast<uint16_t*>(from) - 1, to);
-
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 4 * sizeof(uint16_t));
}
static void repatchInt32(void* where, int32_t value)
@@ -1801,8 +1862,6 @@ public:
ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
setInt32(where, value);
-
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(where) - 4, 4 * sizeof(uint16_t));
}
static void repatchPointer(void* where, void* value)
@@ -1810,8 +1869,6 @@ public:
ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
setPointer(where, value);
-
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(where) - 4, 4 * sizeof(uint16_t));
}
static void repatchLoadPtrToLEA(void* where)
@@ -1952,7 +2009,54 @@ private:
return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b);
}
- static bool canBeShortJump(const uint16_t* instruction, const void* target, bool& mayTriggerErrata)
+ static bool canBeJumpT1(const uint16_t* instruction, const void* target)
+ {
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ // It does not appear to be documented in the ARM ARM (big surprise), but
+ // for OP_B_T1 the branch displacement encoded in the instruction is 2
+ // less than the actual displacement.
+ relative -= 2;
+ return ((relative << 23) >> 23) == relative;
+ }
+
+ static bool canBeJumpT2(const uint16_t* instruction, const void* target)
+ {
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ // It does not appear to be documented in the ARM ARM (big surprise), but
+ // for OP_B_T2 the branch displacement encoded in the instruction is 2
+ // less than the actual displacement.
+ relative -= 2;
+ return ((relative << 20) >> 20) == relative;
+ }
+
+ static bool canBeJumpT3(const uint16_t* instruction, const void* target, bool& mayTriggerErrata)
+ {
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ // From Cortex-A8 errata:
+ // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and
+ // the target of the branch falls within the first region it is
+ // possible for the processor to incorrectly determine the branch
+ // instruction, and it is also possible in some cases for the processor
+ // to enter a deadlock state.
+ // The instruction is spanning two pages if it ends at an address ending 0x002
+ bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002);
+ mayTriggerErrata = spansTwo4K;
+ // The target is in the first page if the jump branch back by [3..0x1002] bytes
+ bool targetInFirstPage = (relative >= -0x1002) && (relative < -2);
+ bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage;
+ return ((relative << 11) >> 11) == relative && !wouldTriggerA8Errata;
+ }
+
+ static bool canBeJumpT4(const uint16_t* instruction, const void* target, bool& mayTriggerErrata)
{
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
@@ -1972,50 +2076,127 @@ private:
bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage;
return ((relative << 7) >> 7) == relative && !wouldTriggerA8Errata;
}
-
- static void linkLongJump(uint16_t* instruction, void* target)
+
+ void linkJumpT1(Condition cond, uint16_t* instruction, void* target)
{
- linkJumpAbsolute(instruction, target);
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+ ASSERT(canBeJumpT1(instruction, target));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ // It does not appear to be documented in the ARM ARM (big surprise), but
+ // for OP_B_T1 the branch displacement encoded in the instruction is 2
+ // less than the actual displacement.
+ relative -= 2;
+
+ // All branch offsets should be an even distance.
+ ASSERT(!(relative & 1));
+ instruction[-1] = OP_B_T1 | ((cond & 0xf) << 8) | ((relative & 0x1fe) >> 1);
}
- static void linkShortJump(uint16_t* instruction, void* target)
+ static void linkJumpT2(uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+ ASSERT(canBeJumpT2(instruction, target));
intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ // It does not appear to be documented in the ARM ARM (big surprise), but
+ // for OP_B_T2 the branch displacement encoded in the instruction is 2
+ // less than the actual displacement.
+ relative -= 2;
+
+ // All branch offsets should be an even distance.
+ ASSERT(!(relative & 1));
+ instruction[-1] = OP_B_T2 | ((relative & 0xffe) >> 1);
+ }
+
+ void linkJumpT3(Condition cond, uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
bool scratch;
UNUSED_PARAM(scratch);
- ASSERT(canBeShortJump(instruction, target, scratch));
+ ASSERT(canBeJumpT3(instruction, target, scratch));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+
+ // All branch offsets should be an even distance.
+ ASSERT(!(relative & 1));
+ instruction[-2] = OP_B_T3a | ((relative & 0x100000) >> 10) | ((cond & 0xf) << 6) | ((relative & 0x3f000) >> 12);
+ instruction[-1] = OP_B_T3b | ((relative & 0x80000) >> 8) | ((relative & 0x40000) >> 5) | ((relative & 0xffe) >> 1);
+ }
+
+ static void linkJumpT4(uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+ bool scratch;
+ UNUSED_PARAM(scratch);
+ ASSERT(canBeJumpT4(instruction, target, scratch));
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
// ARM encoding for the top two bits below the sign bit is 'peculiar'.
if (relative >= 0)
relative ^= 0xC00000;
-
+
// All branch offsets should be an even distance.
ASSERT(!(relative & 1));
instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
}
-
+
+ void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ instruction[-3] = ifThenElse(cond) | OP_IT;
+ linkJumpT4(instruction, target);
+ }
+
+ static void linkBX(uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip;
+ ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1));
+ ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16));
+ instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
+ instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16);
+ instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
+ instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16);
+ instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
+ }
+
+ void linkConditionalBX(Condition cond, uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ linkBX(instruction, target);
+ instruction[-6] = ifThenElse(cond, true, true) | OP_IT;
+ }
+
static void linkJumpAbsolute(uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
-
+
ASSERT((isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1))
- || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)));
-
- intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)));
+
bool scratch;
- if (canBeShortJump(instruction, target, scratch)) {
- // ARM encoding for the top two bits below the sign bit is 'peculiar'.
- if (relative >= 0)
- relative ^= 0xC00000;
-
- // All branch offsets should be an even distance.
- ASSERT(!(relative & 1));
+ if (canBeJumpT4(instruction, target, scratch)) {
// There may be a better way to fix this, but right now put the NOPs first, since in the
// case of an conditional branch this will be coming after an ITTT predicating *three*
// instructions! Looking backwards to modify the ITTT to an IT is not easy, due to
@@ -2024,8 +2205,7 @@ private:
instruction[-5] = OP_NOP_T1;
instruction[-4] = OP_NOP_T2a;
instruction[-3] = OP_NOP_T2b;
- instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
- instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
+ linkJumpT4(instruction, target);
} else {
const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip;
ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1));
@@ -2037,7 +2217,7 @@ private:
instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
}
}
-
+
static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm)
{
return op | (imm.m_value.i << 10) | imm.m_value.imm4;
diff --git a/JavaScriptCore/assembler/LinkBuffer.h b/JavaScriptCore/assembler/LinkBuffer.h
index 408deb0..e1dca0b 100644
--- a/JavaScriptCore/assembler/LinkBuffer.h
+++ b/JavaScriptCore/assembler/LinkBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,9 @@
#if ENABLE(ASSEMBLER)
+#define DUMP_LINK_STATISTICS 0
+#define DUMP_CODE 0
+
#include <MacroAssembler.h>
#include <wtf/Noncopyable.h>
@@ -235,12 +238,14 @@ private:
target = linkBase + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());
JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], linkBase + writePtr, target);
-
- // Step back in the write stream
- int32_t delta = m_assembler->jumpSizeDelta(jumpLinkType);
- if (delta) {
- writePtr -= delta;
- m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr);
+ // Compact branch if we can...
+ if (m_assembler->canCompact(jumpsToLink[i].type())) {
+ // Step back in the write stream
+ int32_t delta = m_assembler->jumpSizeDelta(jumpsToLink[i].type(), jumpLinkType);
+ if (delta) {
+ writePtr -= delta;
+ m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr);
+ }
}
jumpsToLink[i].setFrom(writePtr);
}
@@ -261,6 +266,13 @@ private:
jumpsToLink.clear();
m_size = writePtr + m_assembler->size() - readPtr;
m_executablePool->returnLastBytes(initialSize - m_size);
+
+#if DUMP_LINK_STATISTICS
+ dumpLinkStatistics(m_code, initialSize, m_size);
+#endif
+#if DUMP_CODE
+ dumpCode(m_code, m_size);
+#endif
#endif
}
@@ -275,6 +287,53 @@ private:
ExecutableAllocator::cacheFlush(code(), m_size);
}
+#if DUMP_LINK_STATISTICS
+ static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize)
+ {
+ static unsigned linkCount = 0;
+ static unsigned totalInitialSize = 0;
+ static unsigned totalFinalSize = 0;
+ linkCount++;
+ totalInitialSize += initialSize;
+ totalFinalSize += finalSize;
+ printf("link %p: orig %u, compact %u (delta %u, %.2f%%)\n",
+ code, static_cast<unsigned>(initialSize), static_cast<unsigned>(finalSize),
+ static_cast<unsigned>(initialSize - finalSize),
+ 100.0 * (initialSize - finalSize) / initialSize);
+ printf("\ttotal %u: orig %u, compact %u (delta %u, %.2f%%)\n",
+ linkCount, totalInitialSize, totalFinalSize, totalInitialSize - totalFinalSize,
+ 100.0 * (totalInitialSize - totalFinalSize) / totalInitialSize);
+ }
+#endif
+
+#if DUMP_CODE
+ static void dumpCode(void* code, size_t size)
+ {
+#if CPU(ARM_THUMB2)
+ // Dump the generated code in an asm file format that can be assembled and then disassembled
+ // for debugging purposes. For example, save this output as jit.s:
+ // gcc -arch armv7 -c jit.s
+ // otool -tv jit.o
+ static unsigned codeCount = 0;
+ unsigned short* tcode = static_cast<unsigned short*>(code);
+ size_t tsize = size / sizeof(short);
+ char nameBuf[128];
+ snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
+ printf("\t.syntax unified\n"
+ "\t.section\t__TEXT,__text,regular,pure_instructions\n"
+ "\t.globl\t%s\n"
+ "\t.align 2\n"
+ "\t.code 16\n"
+ "\t.thumb_func\t%s\n"
+ "# %p\n"
+ "%s:\n", nameBuf, nameBuf, code, nameBuf);
+
+ for (unsigned i = 0; i < tsize; i++)
+ printf("\t.short\t0x%x\n", tcode[i]);
+#endif
+ }
+#endif
+
RefPtr<ExecutablePool> m_executablePool;
size_t m_size;
void* m_code;
diff --git a/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index a1539f2..fe5d052 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
public:
typedef ARMv7Assembler::LinkRecord LinkRecord;
+ typedef ARMv7Assembler::JumpType JumpType;
typedef ARMv7Assembler::JumpLinkType JumpLinkType;
MacroAssemblerARMv7()
@@ -57,9 +58,11 @@ public:
void endUninterruptedSequence() { m_inUninterruptedSequence = false; }
Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); }
void* unlinkedCode() { return m_assembler.unlinkedCode(); }
+ bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); }
+ JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(jumpType, from, to); }
JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(record, from, to); }
void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); }
- int jumpSizeDelta(JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpLinkType); }
+ int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpType, jumpLinkType); }
void link(LinkRecord& record, uint8_t* from, uint8_t* to) { return m_assembler.link(record, from, to); }
struct ArmAddress {
@@ -986,14 +989,14 @@ public:
void jump(RegisterID target)
{
- m_assembler.bx(target, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition);
+ m_assembler.bx(target, ARMv7Assembler::JumpFixed);
}
// Address is a memory location containing the address to jump to
void jump(Address address)
{
load32(address, dataTempRegister);
- m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition);
+ m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed);
}
@@ -1082,29 +1085,29 @@ public:
Call nearCall()
{
moveFixedWidthEncoding(Imm32(0), dataTempRegister);
- return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::LinkableNear);
+ return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::LinkableNear);
}
Call call()
{
moveFixedWidthEncoding(Imm32(0), dataTempRegister);
- return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::Linkable);
+ return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
}
Call call(RegisterID target)
{
- return Call(m_assembler.blx(target, ARMv7Assembler::JumpFullSize), Call::None);
+ return Call(m_assembler.blx(target, ARMv7Assembler::JumpFixed), Call::None);
}
Call call(Address address)
{
load32(address, dataTempRegister);
- return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::None);
+ return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::None);
}
void ret()
{
- m_assembler.bx(linkRegister, ARMv7Assembler::JumpFullSize);
+ m_assembler.bx(linkRegister, ARMv7Assembler::JumpFixed);
}
void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
@@ -1204,7 +1207,7 @@ public:
{
// Like a normal call, but don't link.
moveFixedWidthEncoding(Imm32(0), dataTempRegister);
- return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::Linkable);
+ return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
}
Call makeTailRecursiveCall(Jump oldJump)
@@ -1228,14 +1231,14 @@ protected:
ARMv7Assembler::JmpSrc makeJump()
{
moveFixedWidthEncoding(Imm32(0), dataTempRegister);
- return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition);
+ return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition);
}
ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond)
{
m_assembler.it(cond, true, true);
moveFixedWidthEncoding(Imm32(0), dataTempRegister);
- return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpCondition, cond);
+ return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond);
}
ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); }
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
index 6c0696e..55101d4 100644
--- a/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -34,10 +34,11 @@
#include "Debugger.h"
#include "Interpreter.h"
#include "JIT.h"
+#include "JSActivation.h"
#include "JSFunction.h"
#include "JSStaticScopeObject.h"
#include "JSValue.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <stdio.h>
#include <wtf/StringExtras.h>
@@ -52,7 +53,7 @@ static UString escapeQuotes(const UString& str)
UString result = str;
size_t pos = 0;
while ((pos = result.find('\"', pos)) != notFound) {
- result = makeString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1));
+ result = makeUString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1));
pos += 4;
}
return result;
@@ -64,19 +65,19 @@ static UString valueToSourceString(ExecState* exec, JSValue val)
return "0";
if (val.isString())
- return makeString("\"", escapeQuotes(val.toString(exec)), "\"");
+ return makeUString("\"", escapeQuotes(val.toString(exec)), "\"");
return val.toString(exec);
}
static CString constantName(ExecState* exec, int k, JSValue value)
{
- return makeString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8();
+ return makeUString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8();
}
static CString idName(int id0, const Identifier& ident)
{
- return makeString(ident.ustring(), "(@id", UString::number(id0), ")").utf8();
+ return makeUString(ident.ustring(), "(@id", UString::number(id0), ")").utf8();
}
CString CodeBlock::registerName(ExecState* exec, int r) const
@@ -87,7 +88,7 @@ CString CodeBlock::registerName(ExecState* exec, int r) const
if (isConstantRegisterIndex(r))
return constantName(exec, r, getConstant(r));
- return makeString("r", UString::number(r)).utf8();
+ return makeUString("r", UString::number(r)).utf8();
}
static UString regexpToSourceString(RegExp* regExp)
@@ -101,12 +102,12 @@ static UString regexpToSourceString(RegExp* regExp)
if (regExp->multiline())
postfix[index] = 'm';
- return makeString("/", regExp->pattern(), postfix);
+ return makeUString("/", regExp->pattern(), postfix);
}
static CString regexpName(int re, RegExp* regexp)
{
- return makeString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8();
+ return makeUString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8();
}
static UString pointerToSourceString(void* p)
@@ -485,9 +486,9 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] enter\n", location);
break;
}
- case op_enter_with_activation: {
+ case op_create_activation: {
int r0 = (++it)->u.operand;
- printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).data());
+ printf("[%4d] create_activation %s\n", location, registerName(exec, r0).data());
break;
}
case op_create_arguments: {
@@ -516,6 +517,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] convert_this %s\n", location, registerName(exec, r0).data());
break;
}
+ case op_convert_this_strict: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] convert_this_strict %s\n", location, registerName(exec, r0).data());
+ break;
+ }
case op_new_object: {
int r0 = (++it)->u.operand;
printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).data());
@@ -722,9 +728,8 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int id0 = (++it)->u.operand;
JSValue scope = JSValue((++it)->u.jsCell);
++it;
- int depth = it[2].u.operand;
+ int depth = (++it)->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;
break;
}
case op_get_scoped_var: {
@@ -756,7 +761,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_resolve_base: {
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
- printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
+ int isStrict = (++it)->u.operand;
+ printf("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
+ break;
+ }
+ case op_ensure_property_exists: {
+ int r0 = (++it)->u.operand;
+ int id0 = (++it)->u.operand;
+ printf("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
break;
}
case op_resolve_with_base: {
@@ -1134,9 +1146,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_next_pname: {
int dest = it[1].u.operand;
- int iter = it[4].u.operand;
- int offset = it[5].u.operand;
- printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, iter).data(), offset, location + offset);
+ int base = it[2].u.operand;
+ int i = it[3].u.operand;
+ int size = it[4].u.operand;
+ int iter = it[5].u.operand;
+ int offset = it[6].u.operand;
+ printf("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset);
it += OPCODE_LENGTH(op_next_pname) - 1;
break;
}
@@ -1371,6 +1386,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo
, m_needsFullScopeChain(ownerExecutable->needsActivation())
, m_usesEval(ownerExecutable->usesEval())
, m_isNumericCompareFunction(false)
+ , m_isStrictMode(ownerExecutable->isStrictMode())
, m_codeType(codeType)
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
@@ -1542,6 +1558,10 @@ bool CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
ASSERT(!m_rareData || !m_rareData->m_exceptionHandlers.size());
ScopeChainNode* scopeChain = callFrame->scopeChain();
if (m_needsFullScopeChain) {
+ if (codeType() == FunctionCode && !callFrame->r(activationRegister()).jsValue()) {
+ createActivation(callFrame);
+ scopeChain = callFrame->scopeChain();
+ }
ScopeChain sc(scopeChain);
int scopeDelta = sc.localDepth();
if (m_codeType == EvalCode)
@@ -1553,7 +1573,7 @@ bool CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
scopeChain = scopeChain->next;
}
- m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(m_globalData, scopeChain, this);
+ m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(scopeChain, this);
return m_exceptionInfo;
}
@@ -1765,4 +1785,14 @@ void CodeBlock::shrinkToFit()
}
}
+void CodeBlock::createActivation(CallFrame* callFrame)
+{
+ ASSERT(codeType() == FunctionCode);
+ ASSERT(needsFullScopeChain());
+ ASSERT(!callFrame->r(activationRegister()).jsValue());
+ JSActivation* activation = new (callFrame) JSActivation(callFrame, static_cast<FunctionExecutable*>(ownerExecutable()));
+ callFrame->r(activationRegister()) = JSValue(activation);
+ callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
index cda4530..e4ebeb8 100644
--- a/JavaScriptCore/bytecode/CodeBlock.h
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -297,9 +297,11 @@ namespace JSC {
void printStructure(const char* name, const Instruction*, int operand) const;
#endif
+ bool isStrictMode() const { return m_isStrictMode; }
+
inline bool isKnownNotImmediate(int index)
{
- if (index == m_thisRegister)
+ if (index == m_thisRegister && !m_isStrictMode)
return true;
if (isConstantRegisterIndex(index))
@@ -408,6 +410,15 @@ namespace JSC {
ASSERT(usesArguments());
return m_argumentsRegister;
}
+ void setActivationRegister(int activationRegister)
+ {
+ m_activationRegister = activationRegister;
+ }
+ int activationRegister()
+ {
+ ASSERT(needsFullScopeChain());
+ return m_activationRegister;
+ }
bool usesArguments() const { return m_argumentsRegister != -1; }
CodeType codeType() const { return m_codeType; }
@@ -420,6 +431,8 @@ namespace JSC {
unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
+ void createActivation(CallFrame*);
+
#if ENABLE(INTERPRETER)
void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); }
@@ -548,10 +561,12 @@ namespace JSC {
int m_thisRegister;
int m_argumentsRegister;
+ int m_activationRegister;
bool m_needsFullScopeChain;
bool m_usesEval;
bool m_isNumericCompareFunction;
+ bool m_isStrictMode;
CodeType m_codeType;
diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h
index 7c4cb33..edd575f 100644
--- a/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -43,20 +43,20 @@ namespace JSC {
class EvalCodeCache {
public:
- PassRefPtr<EvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
+ PassRefPtr<EvalExecutable> get(ExecState* exec, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
{
RefPtr<EvalExecutable> evalExecutable;
- if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
+ if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
evalExecutable = m_cacheMap.get(evalSource.impl());
if (!evalExecutable) {
- evalExecutable = EvalExecutable::create(exec, makeSource(evalSource));
+ evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
exceptionValue = evalExecutable->compile(exec, scopeChain);
if (exceptionValue)
return 0;
- if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
+ if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
m_cacheMap.set(evalSource.impl(), evalExecutable);
}
diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h
index 03f6573..e1ef01e 100644
--- a/JavaScriptCore/bytecode/Opcode.h
+++ b/JavaScriptCore/bytecode/Opcode.h
@@ -39,12 +39,13 @@ namespace JSC {
#define FOR_EACH_OPCODE_ID(macro) \
macro(op_enter, 1) \
- macro(op_enter_with_activation, 2) \
+ macro(op_create_activation, 2) \
macro(op_init_lazy_reg, 2) \
macro(op_create_arguments, 2) \
macro(op_create_this, 3) \
macro(op_get_callee, 2) \
macro(op_convert_this, 2) \
+ macro(op_convert_this_strict, 2) \
\
macro(op_new_object, 2) \
macro(op_new_array, 4) \
@@ -99,7 +100,8 @@ namespace JSC {
macro(op_put_scoped_var, 4) \
macro(op_get_global_var, 3) \
macro(op_put_global_var, 3) \
- macro(op_resolve_base, 3) \
+ macro(op_resolve_base, 4) \
+ macro(op_ensure_property_exists, 3) \
macro(op_resolve_with_base, 4) \
macro(op_get_by_id, 8) \
macro(op_get_by_id_self, 8) \
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 986709b..f34c38c 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -214,6 +214,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
, m_nextGlobalIndex(-1)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
@@ -306,10 +307,14 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
, m_codeType(FunctionCode)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_hasCreatedActivation(false)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
+#ifndef NDEBUG
+ , m_lastOpcodePosition(0)
+#endif
, m_emitNodeDepth(0)
, m_usesExceptions(false)
, m_regeneratingForExceptionInfo(false)
@@ -319,13 +324,13 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
m_codeBlock->setNeedsFullScopeChain(true);
codeBlock->setGlobalData(m_globalData);
-
+
+ emitOpcode(op_enter);
if (m_codeBlock->needsFullScopeChain()) {
m_activationRegister = addVar();
- emitOpcode(op_enter_with_activation);
- instructions().append(m_activationRegister->index());
- } else
- emitOpcode(op_enter);
+ emitInitLazyRegister(m_activationRegister);
+ m_codeBlock->setActivationRegister(m_activationRegister->index());
+ }
// Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments'
// object, if created.
@@ -341,6 +346,11 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
emitInitLazyRegister(argumentsRegister);
emitInitLazyRegister(unmodifiedArgumentsRegister);
+
+ if (m_codeBlock->isStrictMode()) {
+ emitOpcode(op_create_arguments);
+ instructions().append(argumentsRegister->index());
+ }
// 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>),
@@ -356,11 +366,17 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
// Captured variables and functions go first so that activations don't have
// to step over the non-captured locals to mark them.
+ m_hasCreatedActivation = false;
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)) {
+ if (!m_hasCreatedActivation) {
+ m_hasCreatedActivation = true;
+ emitOpcode(op_create_activation);
+ instructions().append(m_activationRegister->index());
+ }
m_functions.add(ident.impl());
emitNewFunction(addVar(ident, false), function);
}
@@ -371,7 +387,13 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
}
}
- bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables();
+ bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !debugger;
+ if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
+ m_hasCreatedActivation = true;
+ emitOpcode(op_create_activation);
+ instructions().append(m_activationRegister->index());
+ }
+
codeBlock->m_numCapturedVars = codeBlock->m_numVars;
m_firstLazyFunction = codeBlock->m_numVars;
for (size_t i = 0; i < functionStack.size(); ++i) {
@@ -399,7 +421,6 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
if (debugger)
codeBlock->m_numCapturedVars = codeBlock->m_numVars;
-
FunctionParameters& parameters = *functionBody->parameters();
size_t parameterCount = parameters.size();
@@ -429,7 +450,10 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
instructions().append(m_thisRegister.index());
instructions().append(funcProto->index());
} else if (functionBody->usesThis() || m_shouldEmitDebugHooks) {
- emitOpcode(op_convert_this);
+ if (codeBlock->isStrictMode())
+ emitOpcode(op_convert_this_strict);
+ else
+ emitOpcode(op_convert_this);
instructions().append(m_thisRegister.index());
}
}
@@ -448,10 +472,14 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
, m_codeType(EvalCode)
, m_nextConstantOffset(0)
, m_globalConstantIndex(0)
+ , m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
+#ifndef NDEBUG
+ , m_lastOpcodePosition(0)
+#endif
, m_emitNodeDepth(0)
, m_usesExceptions(false)
, m_regeneratingForExceptionInfo(false)
@@ -1249,6 +1277,7 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier
emitOpcode(op_resolve_base);
instructions().append(dst->index());
instructions().append(addConstant(property));
+ instructions().append(false);
return dst;
}
@@ -1256,6 +1285,32 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier
return emitLoad(dst, JSValue(globalObject));
}
+RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Identifier& property)
+{
+ if (!m_codeBlock->isStrictMode())
+ return emitResolveBase(dst, property);
+ size_t depth = 0;
+ int index = 0;
+ JSObject* globalObject = 0;
+ bool requiresDynamicChecks = false;
+ findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
+ if (!globalObject || requiresDynamicChecks) {
+ // We can't optimise at all :-(
+ emitOpcode(op_resolve_base);
+ instructions().append(dst->index());
+ instructions().append(addConstant(property));
+ instructions().append(true);
+ return dst;
+ }
+
+ // Global object is the base
+ RefPtr<RegisterID> result = emitLoad(dst, JSValue(globalObject));
+ emitOpcode(op_ensure_property_exists);
+ instructions().append(dst->index());
+ instructions().append(addConstant(property));
+ return result.get();
+}
+
RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
{
size_t depth = 0;
@@ -1504,6 +1559,7 @@ RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBody
RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
{
+ createActivationIfNecessary();
emitOpcode(op_new_func);
instructions().append(dst->index());
instructions().append(index);
@@ -1523,7 +1579,8 @@ RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExp
{
FunctionBodyNode* function = n->body();
unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function));
-
+
+ createActivationIfNecessary();
emitOpcode(op_new_func_exp);
instructions().append(r0->index());
instructions().append(index);
@@ -1541,10 +1598,26 @@ void BytecodeGenerator::createArgumentsIfNecessary()
return;
ASSERT(m_codeBlock->usesArguments());
+ // If we're in strict mode we tear off the arguments on function
+ // entry, so there's no need to check if we need to create them
+ // now
+ if (m_codeBlock->isStrictMode())
+ return;
+
emitOpcode(op_create_arguments);
instructions().append(m_codeBlock->argumentsRegister());
}
+void BytecodeGenerator::createActivationIfNecessary()
+{
+ if (m_hasCreatedActivation)
+ return;
+ if (!m_codeBlock->needsFullScopeChain())
+ return;
+ emitOpcode(op_create_activation);
+ instructions().append(m_activationRegister->index());
+}
+
RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
{
return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset);
@@ -1648,7 +1721,8 @@ RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
emitOpcode(op_tear_off_activation);
instructions().append(m_activationRegister->index());
instructions().append(m_codeBlock->argumentsRegister());
- } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time.
+ } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1
+ && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time.
emitOpcode(op_tear_off_arguments);
instructions().append(m_codeBlock->argumentsRegister());
}
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 2afa0c4..d0e4a6b 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -329,6 +329,7 @@ namespace JSC {
RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue globalObject);
RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property);
+ RegisterID* emitResolveBaseForPut(RegisterID* dst, const Identifier& property);
RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property);
void emitMethodCheck();
@@ -419,13 +420,15 @@ namespace JSC {
}
bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
+
+ bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
private:
void emitOpcode(OpcodeID);
void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
- void rewindBinaryOp();
- void rewindUnaryOp();
+ ALWAYS_INLINE void rewindBinaryOp();
+ ALWAYS_INLINE void rewindUnaryOp();
PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
@@ -499,12 +502,12 @@ namespace JSC {
PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body)
{
- return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
+ return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
PassRefPtr<FunctionExecutable> makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
{
- return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
+ return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
RegisterID* emitInitLazyRegister(RegisterID*);
@@ -518,6 +521,7 @@ namespace JSC {
RegisterID* emitThrowExpressionTooDeepException();
void createArgumentsIfNecessary();
+ void createActivationIfNecessary();
RegisterID* createLazyRegisterIfNecessary(RegisterID*);
bool m_shouldEmitDebugHooks;
@@ -558,6 +562,7 @@ namespace JSC {
int m_globalVarStorageOffset;
+ bool m_hasCreatedActivation;
int m_firstLazyFunction;
int m_lastLazyFunction;
HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int> > m_lazyFunctions;
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2cc1a3f..449cae9 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -42,7 +42,7 @@
#include "RegExpCache.h"
#include "RegExpObject.h"
#include "SamplingTool.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <wtf/Assertions.h>
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/Threading.h>
@@ -80,7 +80,7 @@ static void substitute(UString& string, const UString& substring)
{
size_t position = string.find("%s");
ASSERT(position != notFound);
- string = makeString(string.substringSharingImpl(0, position), substring, string.substringSharingImpl(position + 2));
+ string = makeUString(string.substringSharingImpl(0, position), substring, string.substringSharingImpl(position + 2));
}
RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* message)
@@ -371,7 +371,7 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re
{
RefPtr<RegisterID> func = generator.emitNode(m_expr);
CallArguments callArguments(generator, m_args);
- generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
@@ -381,7 +381,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
{
if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
CallArguments callArguments(generator, m_args);
- generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), local.get(), callArguments, divot(), startOffset(), endOffset());
}
@@ -392,7 +392,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
CallArguments callArguments(generator, m_args);
- generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
@@ -455,7 +455,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
} else {
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
- generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
generator.emitJump(end.get());
}
@@ -513,7 +513,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
} else {
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
- generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
}
} else {
@@ -1231,7 +1231,7 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
return value;
}
- RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
+ RefPtr<RegisterID> base = generator.emitResolveBaseForPut(generator.newTemporary(), m_ident);
if (dst == generator.ignoredResult())
dst = 0;
RegisterID* value = generator.emitNode(dst, m_right);
@@ -1605,7 +1605,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
if (!propertyName) {
propertyName = generator.newTemporary();
RefPtr<RegisterID> protect = propertyName;
- RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
+ RegisterID* base = generator.emitResolveBaseForPut(generator.newTemporary(), ident);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base, ident, propertyName);
diff --git a/JavaScriptCore/debugger/Debugger.cpp b/JavaScriptCore/debugger/Debugger.cpp
index cbcbd21..17dfdf7 100644
--- a/JavaScriptCore/debugger/Debugger.cpp
+++ b/JavaScriptCore/debugger/Debugger.cpp
@@ -101,7 +101,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
{
CallFrame* globalCallFrame = globalObject->globalExec();
- RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script));
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain());
if (error)
return error;
diff --git a/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index 32f65dd..c98c7cc 100644
--- a/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -88,7 +88,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
if (!m_callFrame->codeBlock())
return JSValue();
- RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script));
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
JSObject* error = eval->compile(m_callFrame, m_callFrame->scopeChain());
if (error)
return error;
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 5943ece..632571d 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -59,6 +59,7 @@
#include "RegExpPrototype.h"
#include "Register.h"
#include "SamplingTool.h"
+#include "StrictEvalActivation.h"
#include <limits.h>
#include <stdio.h>
#include <wtf/Threading.h>
@@ -127,6 +128,12 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
ASSERT(iter != end);
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
++iter;
ASSERT(iter != end);
@@ -140,6 +147,7 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
+ ASSERT(result);
callFrame->r(dst) = JSValue(result);
return true;
}
@@ -203,6 +211,12 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
ASSERT(iter != end);
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
JSObject* o = *iter;
if (o->hasCustomProperties()) {
@@ -214,6 +228,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
+ ASSERT(result);
callFrame->r(dst) = JSValue(result);
return true;
}
@@ -230,6 +245,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
if (structure == globalObject->structure()) {
callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset));
+ ASSERT(callFrame->r(dst).jsValue());
return true;
}
@@ -243,6 +259,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
globalObject->structure()->ref();
vPC[3] = globalObject->structure();
vPC[4] = slot.cachedOffset();
+ ASSERT(result);
callFrame->r(dst) = JSValue(result);
return true;
}
@@ -250,6 +267,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
+ ASSERT(result);
callFrame->r(dst) = JSValue(result);
return true;
}
@@ -262,7 +280,14 @@ NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vP
{
int dst = vPC[1].u.operand;
int property = vPC[2].u.operand;
- callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
+ bool isStrictPut = vPC[3].u.operand;
+ Identifier ident = callFrame->codeBlock()->identifier(property);
+ JSValue result = JSC::resolveBase(callFrame, ident, callFrame->scopeChain(), isStrictPut);
+ if (!result) {
+ callFrame->r(dst) = result;
+ ASSERT(callFrame->r(dst).jsValue());
+ } else
+ callFrame->globalData().exception = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
}
NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
@@ -371,14 +396,18 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
UString programSource = asString(program)->value(callFrame);
if (callFrame->hadException())
return JSValue();
-
- LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
- if (JSValue parsedObject = preparser.tryLiteralParse())
- return parsedObject;
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ if (!codeBlock->isStrictMode()) {
+ // FIXME: We can use the preparser in strict mode, we just need additional logic
+ // to prevent duplicates.
+ LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
+ if (JSValue parsedObject = preparser.tryLiteralParse())
+ return parsedObject;
+ }
ScopeChainNode* scopeChain = callFrame->scopeChain();
- CodeBlock* codeBlock = callFrame->codeBlock();
- RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
+ RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
JSValue result = jsUndefined();
if (eval)
@@ -535,13 +564,19 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
// If this call frame created an activation or an 'arguments' object, tear it off.
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
+ if (!callFrame->r(oldCodeBlock->activationRegister()).jsValue()) {
+ oldCodeBlock->createActivation(callFrame);
+ scopeChain = callFrame->scopeChain();
+ }
while (!scopeChain->object->inherits(&JSActivation::info))
scopeChain = scopeChain->pop();
JSActivation* activation = asActivation(scopeChain->object);
activation->copyRegisters();
- if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
- asArguments(arguments)->setActivation(activation);
- } else if (oldCodeBlock->usesArguments()) {
+ if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
+ if (!oldCodeBlock->isStrictMode())
+ asArguments(arguments)->setActivation(activation);
+ }
+ } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) {
if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
asArguments(arguments)->copyRegisters();
}
@@ -641,12 +676,23 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
}
// Shrink the JS stack, in case stack overflow made it huge.
- m_registerFile.shrink(callFrame->registers() + callFrame->codeBlock()->m_numCalleeRegisters);
+ Register* highWaterMark = callFrame->registers() + callFrame->codeBlock()->m_numCalleeRegisters;
+ for (CallFrame* callerFrame = callFrame->callerFrame()->removeHostCallFrameFlag(); callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) {
+ CodeBlock* codeBlock = callerFrame->codeBlock();
+ if (!codeBlock)
+ continue;
+ Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters;
+ highWaterMark = max(highWaterMark, callerHighWaterMark);
+ }
+ m_registerFile.shrink(highWaterMark);
// Unwind the scope chain within the exception handler's call frame.
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChain sc(scopeChain);
- int scopeDelta = depth(codeBlock, sc) - handler->scopeDepth;
+ int scopeDelta = 0;
+ if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode
+ || callFrame->r(codeBlock->activationRegister()).jsValue())
+ scopeDelta = depth(codeBlock, sc) - handler->scopeDepth;
ASSERT(scopeDelta >= 0);
while (scopeDelta--)
scopeChain = scopeChain->pop();
@@ -1036,7 +1082,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
}
EvalCodeBlock* codeBlock = &eval->generatedBytecode();
- JSVariableObject* variableObject;
+ JSObject* variableObject;
for (ScopeChainNode* node = scopeChain; ; node = node->next) {
ASSERT(node);
if (node->object->isVariableObject()) {
@@ -1047,7 +1093,13 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
unsigned numVariables = codeBlock->numVariables();
int numFunctions = codeBlock->numberOfFunctionDecls();
+ bool pushedScope = false;
if (numVariables || numFunctions) {
+ if (codeBlock->isStrictMode()) {
+ variableObject = new (callFrame) StrictEvalActivation(callFrame);
+ scopeChain = scopeChain->push(variableObject);
+ pushedScope = true;
+ }
// Scope for BatchedTransitionOptimizer
BatchedTransitionOptimizer optimizer(variableObject);
@@ -1070,6 +1122,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
if (!m_registerFile.grow(newEnd)) {
*exception = createStackOverflowError(callFrame);
+ if (pushedScope)
+ scopeChain->pop();
return jsNull();
}
@@ -1112,6 +1166,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
(*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
m_registerFile.shrink(oldEnd);
+ if (pushedScope)
+ scopeChain->pop();
return result;
}
@@ -1518,6 +1574,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = vPC[1].u.operand;
int src = vPC[2].u.operand;
+
callFrame->r(dst) = callFrame->r(src);
vPC += OPCODE_LENGTH(op_mov);
@@ -2327,6 +2384,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
ASSERT(iter != end);
+ ASSERT(codeBlock == callFrame->codeBlock());
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
++iter;
ASSERT(iter != end);
@@ -2334,6 +2398,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
callFrame->r(dst) = scope->registerAt(index);
+ ASSERT(callFrame->r(dst).jsValue());
vPC += OPCODE_LENGTH(op_get_scoped_var);
NEXT_INSTRUCTION();
}
@@ -2348,7 +2413,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
+ ASSERT(codeBlock == callFrame->codeBlock());
ASSERT(iter != end);
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
++iter;
ASSERT(iter != end);
@@ -2356,6 +2428,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
+ ASSERT(callFrame->r(value).jsValue());
scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
vPC += OPCODE_LENGTH(op_put_scoped_var);
NEXT_INSTRUCTION();
@@ -2373,6 +2446,24 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
vPC += OPCODE_LENGTH(op_resolve_base);
NEXT_INSTRUCTION();
}
+ DEFINE_OPCODE(op_ensure_property_exists) {
+ /* ensure_property_exists base(r) property(id)
+
+ Throws an exception if property does not exist on base
+ */
+ int base = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ Identifier& ident = codeBlock->identifier(property);
+
+ JSValue baseVal = callFrame->r(base).jsValue();
+ JSObject* baseObject = asObject(baseVal);
+ PropertySlot slot(baseVal);
+ if (!baseObject->getPropertySlot(callFrame, ident, slot)) {
+ exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
+ goto vm_throw;
+ }
+ NEXT_INSTRUCTION();
+ }
DEFINE_OPCODE(op_resolve_with_base) {
/* resolve_with_base baseDst(r) propDst(r) property(id)
@@ -2922,7 +3013,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
Identifier& ident = codeBlock->identifier(property);
- PutPropertySlot slot;
+ PutPropertySlot slot(codeBlock->isStrictMode());
if (direct) {
baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
ASSERT(slot.base() == baseValue);
@@ -3038,7 +3129,7 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
Identifier& ident = codeBlock->identifier(property);
- PutPropertySlot slot;
+ PutPropertySlot slot(codeBlock->isStrictMode());
if (direct) {
baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
ASSERT(slot.base() == baseValue);
@@ -3063,9 +3154,13 @@ skip_id_custom_self:
JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
Identifier& ident = codeBlock->identifier(property);
- JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
+ bool result = baseObj->deleteProperty(callFrame, ident);
+ if (!result && codeBlock->isStrictMode()) {
+ exceptionValue = createTypeError(callFrame, "Unable to delete property.");
+ goto vm_throw;
+ }
CHECK_FOR_EXCEPTION();
- callFrame->r(dst) = result;
+ callFrame->r(dst) = jsBoolean(result);
vPC += OPCODE_LENGTH(op_del_by_id);
NEXT_INSTRUCTION();
}
@@ -3131,8 +3226,8 @@ skip_id_custom_self:
}
if (!arguments) {
Arguments* arguments = new (globalData) Arguments(callFrame);
- callFrame->r(dst) = JSValue(arguments);
- callFrame->r(unmodifiedArgumentsRegister(dst)) = JSValue(arguments);
+ callFrame->r(argumentsRegister) = JSValue(arguments);
+ callFrame->r(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments);
}
// fallthrough
}
@@ -3218,7 +3313,7 @@ skip_id_custom_self:
} else {
Identifier property(callFrame, subscript.toString(callFrame));
if (!globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot;
+ PutPropertySlot slot(codeBlock->isStrictMode());
baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
}
}
@@ -3242,19 +3337,22 @@ skip_id_custom_self:
JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw
JSValue subscript = callFrame->r(property).jsValue();
- JSValue result;
+ bool result;
uint32_t i;
if (subscript.getUInt32(i))
- result = jsBoolean(baseObj->deleteProperty(callFrame, i));
+ result = baseObj->deleteProperty(callFrame, i);
else {
CHECK_FOR_EXCEPTION();
Identifier property(callFrame, subscript.toString(callFrame));
CHECK_FOR_EXCEPTION();
- result = jsBoolean(baseObj->deleteProperty(callFrame, property));
+ result = baseObj->deleteProperty(callFrame, property);
+ }
+ if (!result && codeBlock->isStrictMode()) {
+ exceptionValue = createTypeError(callFrame, "Unable to delete property.");
+ goto vm_throw;
}
-
CHECK_FOR_EXCEPTION();
- callFrame->r(dst) = result;
+ callFrame->r(dst) = jsBoolean(result);
vPC += OPCODE_LENGTH(op_del_by_val);
NEXT_INSTRUCTION();
}
@@ -3658,7 +3756,7 @@ skip_id_custom_self:
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
int shouldCheck = vPC[3].u.operand;
-
+ ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
if (!shouldCheck || !callFrame->r(dst).jsValue())
callFrame->r(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
@@ -3675,7 +3773,8 @@ skip_id_custom_self:
*/
int dst = vPC[1].u.operand;
int funcIndex = vPC[2].u.operand;
-
+
+ ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
FunctionExecutable* function = codeBlock->functionExpr(funcIndex);
JSFunction* func = function->make(callFrame, callFrame->scopeChain());
@@ -3711,7 +3810,8 @@ skip_id_custom_self:
int func = vPC[1].u.operand;
int argCount = vPC[2].u.operand;
int registerOffset = vPC[3].u.operand;
-
+
+ ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
JSValue funcVal = callFrame->r(func).jsValue();
Register* newCallFrame = callFrame->registers() + registerOffset;
@@ -3980,15 +4080,22 @@ skip_id_custom_self:
This opcode appears before op_ret in functions that require full scope chains.
*/
- int src1 = vPC[1].u.operand;
- int src2 = vPC[2].u.operand;
+ int activation = vPC[1].u.operand;
+ int arguments = vPC[2].u.operand;
ASSERT(codeBlock->needsFullScopeChain());
-
- JSActivation* activation = asActivation(callFrame->r(src1).jsValue());
- activation->copyRegisters();
-
- if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src2)).jsValue())
- asArguments(arguments)->setActivation(activation);
+ JSValue activationValue = callFrame->r(activation).jsValue();
+ if (activationValue) {
+ asActivation(activationValue)->copyRegisters();
+
+ if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
+ asArguments(argumentsValue)->setActivation(asActivation(activationValue));
+ } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
+ asArguments(argumentsValue)->copyRegisters();
+
+ if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
+ if (!codeBlock->isStrictMode())
+ asArguments(argumentsValue)->setActivation(asActivation(activationValue));
+ }
vPC += OPCODE_LENGTH(op_tear_off_activation);
NEXT_INSTRUCTION();
@@ -4026,7 +4133,7 @@ skip_id_custom_self:
int result = vPC[1].u.operand;
- if (callFrame->codeBlock()->needsFullScopeChain())
+ if (callFrame->codeBlock()->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue())
callFrame->scopeChain()->deref();
JSValue returnValue = callFrame->r(result).jsValue();
@@ -4067,7 +4174,7 @@ skip_id_custom_self:
int result = vPC[1].u.operand;
- if (codeBlock->needsFullScopeChain())
+ if (codeBlock->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue())
callFrame->scopeChain()->deref();
JSValue returnValue = callFrame->r(result).jsValue();
@@ -4103,25 +4210,20 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_enter);
NEXT_INSTRUCTION();
}
- DEFINE_OPCODE(op_enter_with_activation) {
- /* enter_with_activation dst(r)
-
- Initializes local variables to undefined, creates an activation object,
- places it in dst, and pushes it onto the scope chain.
+ DEFINE_OPCODE(op_create_activation) {
+ /* create_activation dst(r)
- This opcode appears only at the beginning of a code block.
+ If the activation object for this callframe has not yet been created,
+ this creates it and writes it back to dst.
*/
- size_t i = 0;
- for (size_t count = codeBlock->m_numVars; i < count; ++i)
- callFrame->r(i) = jsUndefined();
-
- int dst = vPC[1].u.operand;
- JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
- callFrame->r(dst) = JSValue(activation);
- callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
-
- vPC += OPCODE_LENGTH(op_enter_with_activation);
+ int activationReg = vPC[1].u.operand;
+ if (!callFrame->r(activationReg).jsValue()) {
+ JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
+ callFrame->r(activationReg) = JSValue(activation);
+ callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
+ }
+ vPC += OPCODE_LENGTH(op_create_activation);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_callee) {
@@ -4184,6 +4286,25 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_convert_this);
NEXT_INSTRUCTION();
}
+ DEFINE_OPCODE(op_convert_this_strict) {
+ /* convert_this_strict this(r)
+
+ Takes the value in the 'this' register, and converts it to
+ its "this" form if (and only if) "this" is an object with a
+ custom this conversion
+
+ This opcode should only be used at the beginning of a code
+ block.
+ */
+
+ int thisRegister = vPC[1].u.operand;
+ JSValue thisVal = callFrame->r(thisRegister).jsValue();
+ if (thisVal.isObject() && thisVal.needsThisConversion())
+ callFrame->r(thisRegister) = JSValue(thisVal.toStrictThisObject(callFrame));
+
+ vPC += OPCODE_LENGTH(op_convert_this_strict);
+ NEXT_INSTRUCTION();
+ }
DEFINE_OPCODE(op_init_lazy_reg) {
/* init_lazy_reg dst(r)
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index f145404..f362605 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -53,6 +53,12 @@
extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
#endif
+#if PLATFORM(BREWMP)
+#include <AEEIMemCache1.h>
+#include <AEEMemCache1.bid>
+#include <wtf/brew/RefPtrBrew.h>
+#endif
+
#define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize)
#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4)
@@ -294,6 +300,13 @@ public:
{
CacheRangeFlush(code, size, CACHE_SYNC_ALL);
}
+#elif PLATFORM(BREWMP)
+ static void cacheFlush(void* code, size_t size)
+ {
+ PlatformRefPtr<IMemCache1> memCache = createRefPtrInstance<IMemCache1>(AEECLSID_MemCache1);
+ IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_FLUSH, MEMSPACE_DATACACHE);
+ IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_INVALIDATE, MEMSPACE_INSTCACHE);
+ }
#else
#error "The cacheFlush support is missing on this platform."
#endif
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index a508d0c..0eabdf5 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -186,7 +186,7 @@ void JIT::privateCompileMainPass()
sampleInstruction(currentInstruction);
#endif
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
if (m_labels[m_bytecodeOffset].isUsed())
killLastResultRegister();
#endif
@@ -195,9 +195,6 @@ void JIT::privateCompileMainPass()
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
DEFINE_BINARY_OP(op_del_by_val)
-#if USE(JSVALUE32)
- DEFINE_BINARY_OP(op_div)
-#endif
DEFINE_BINARY_OP(op_in)
DEFINE_BINARY_OP(op_less)
DEFINE_BINARY_OP(op_lesseq)
@@ -207,7 +204,7 @@ void JIT::privateCompileMainPass()
DEFINE_UNARY_OP(op_is_object)
DEFINE_UNARY_OP(op_is_string)
DEFINE_UNARY_OP(op_is_undefined)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
DEFINE_UNARY_OP(op_negate)
#endif
DEFINE_UNARY_OP(op_typeof)
@@ -225,16 +222,15 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_get_callee)
DEFINE_OP(op_create_this)
DEFINE_OP(op_convert_this)
+ DEFINE_OP(op_convert_this_strict)
DEFINE_OP(op_init_lazy_reg)
DEFINE_OP(op_create_arguments)
DEFINE_OP(op_debug)
DEFINE_OP(op_del_by_id)
-#if !USE(JSVALUE32)
DEFINE_OP(op_div)
-#endif
DEFINE_OP(op_end)
DEFINE_OP(op_enter)
- DEFINE_OP(op_enter_with_activation)
+ DEFINE_OP(op_create_activation)
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
DEFINE_OP(op_get_by_id)
@@ -301,6 +297,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_put_setter)
DEFINE_OP(op_resolve)
DEFINE_OP(op_resolve_base)
+ DEFINE_OP(op_ensure_property_exists)
DEFINE_OP(op_resolve_global)
DEFINE_OP(op_resolve_global_dynamic)
DEFINE_OP(op_resolve_skip)
@@ -375,7 +372,7 @@ void JIT::privateCompileSlowCases()
m_callLinkInfoIndex = 0;
for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
@@ -396,9 +393,8 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_call_varargs)
DEFINE_SLOWCASE_OP(op_construct)
DEFINE_SLOWCASE_OP(op_convert_this)
-#if !USE(JSVALUE32)
+ DEFINE_SLOWCASE_OP(op_convert_this_strict)
DEFINE_SLOWCASE_OP(op_div)
-#endif
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_arguments_length)
@@ -596,7 +592,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
return patchBuffer.finalizeCode();
}
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
{
loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject, d)), dst);
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 6b2e70e..3ef0538 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -516,8 +516,7 @@ namespace JSC {
Jump emitJumpIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
-#if USE(JSVALUE64)
-#else
+#if USE(JSVALUE32_64)
JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
{
return emitJumpIfImmediateInteger(reg);
@@ -535,7 +534,7 @@ namespace JSC {
void emitJumpSlowCaseIfNotImmediateNumber(RegisterID);
void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
-#if !USE(JSVALUE64)
+#if USE(JSVALUE32_64)
void emitFastArithDeTagImmediate(RegisterID);
Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
#endif
@@ -738,13 +737,14 @@ namespace JSC {
void emit_op_get_callee(Instruction*);
void emit_op_create_this(Instruction*);
void emit_op_convert_this(Instruction*);
+ void emit_op_convert_this_strict(Instruction*);
void emit_op_create_arguments(Instruction*);
void emit_op_debug(Instruction*);
void emit_op_del_by_id(Instruction*);
void emit_op_div(Instruction*);
void emit_op_end(Instruction*);
void emit_op_enter(Instruction*);
- void emit_op_enter_with_activation(Instruction*);
+ void emit_op_create_activation(Instruction*);
void emit_op_eq(Instruction*);
void emit_op_eq_null(Instruction*);
void emit_op_get_by_id(Instruction*);
@@ -810,6 +810,7 @@ namespace JSC {
void emit_op_put_setter(Instruction*);
void emit_op_resolve(Instruction*);
void emit_op_resolve_base(Instruction*);
+ void emit_op_ensure_property_exists(Instruction*);
void emit_op_resolve_global(Instruction*, bool dynamic = false);
void emit_op_resolve_global_dynamic(Instruction*);
void emit_op_resolve_skip(Instruction*);
@@ -845,6 +846,7 @@ namespace JSC {
void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_convert_this_strict(Instruction*, Vector<SlowCaseEntry>::iterator&);
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&);
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index d75f8b5..d4fa12f 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -60,10 +60,6 @@ void JIT::emit_op_lshift(Instruction* currentInstruction)
emitFastArithImmToInt(regT0);
emitFastArithImmToInt(regT2);
lshift32(regT2, regT0);
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(result);
}
@@ -74,20 +70,10 @@ void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEnt
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
-#if USE(JSVALUE64)
UNUSED_PARAM(op1);
UNUSED_PARAM(op2);
linkSlowCase(iter);
linkSlowCase(iter);
-#else
- // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded.
- Jump notImm1 = getSlowCase(iter);
- Jump notImm2 = getSlowCase(iter);
- linkSlowCase(iter);
- emitGetVirtualRegisters(op1, regT0, op2, regT2);
- notImm1.link(this);
- notImm2.link(this);
-#endif
JITStubCall stubCall(this, cti_op_lshift);
stubCall.addArgument(regT0);
stubCall.addArgument(regT2);
@@ -110,20 +96,11 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
emitGetVirtualRegisters(op1, regT0, op2, regT2);
if (supportsFloatingPointTruncate()) {
Jump lhsIsInt = emitJumpIfImmediateInteger(regT0);
-#if USE(JSVALUE64)
// supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
addSlowCase(emitJumpIfNotImmediateNumber(regT0));
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
-#else
- // supportsFloatingPoint() && !USE(JSVALUE64) => 5 SlowCases (of which 1 IfNotJSCell)
- emitJumpSlowCaseIfNotJSCell(regT0, op1);
- addSlowCase(checkStructure(regT0, m_globalData->numberStructure.get()));
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
-#endif
lhsIsInt.link(this);
emitJumpSlowCaseIfNotImmediateInteger(regT2);
} else {
@@ -133,15 +110,8 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
}
emitFastArithImmToInt(regT2);
rshift32(regT2, regT0);
-#if USE(JSVALUE32)
- signExtend32ToPtr(regT0, regT0);
-#endif
}
-#if USE(JSVALUE64)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- orPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
-#endif
emitPutVirtualRegister(result);
}
@@ -159,17 +129,9 @@ void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(op2, regT2);
} else {
if (supportsFloatingPointTruncate()) {
-#if USE(JSVALUE64)
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
-#else
- linkSlowCaseIfNotJSCell(iter, op1);
- linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
-#endif
// We're reloading op1 to regT0 as we can no longer guarantee that
// we have not munged the operand. It may have already been shifted
// correctly, but it still will not have been tagged.
@@ -206,10 +168,6 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
// as an immediate int.
if (shift < 0 || !(shift & 31))
addSlowCase(branch32(LessThan, regT0, Imm32(0)));
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
return;
@@ -222,10 +180,6 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
emitFastArithImmToInt(regT1);
urshift32(regT1, regT0);
addSlowCase(branch32(LessThan, regT0, Imm32(0)));
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
}
@@ -239,7 +193,6 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
int shift = getConstantOperand(op2).asInt32();
// op1 = regT0
linkSlowCase(iter); // int32 check
-#if USE(JSVALUE64)
if (supportsFloatingPointTruncate()) {
JumpList failures;
failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
@@ -255,18 +208,13 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
failures.link(this);
}
-#endif // JSVALUE64
if (shift < 0 || !(shift & 31))
linkSlowCase(iter); // failed to box in hot path
-#if USE(JSVALUE32)
- linkSlowCase(iter); // Couldn't box result
-#endif
} else {
// op1 = regT0
// op2 = regT1
if (!isOperandConstantImmediateInt(op1)) {
linkSlowCase(iter); // int32 check -- op1 is not an int
-#if USE(JSVALUE64)
if (supportsFloatingPointTruncate()) {
JumpList failures;
failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
@@ -282,14 +230,10 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
failures.link(this);
}
-#endif
}
linkSlowCase(iter); // int32 check - op2 is not an int
linkSlowCase(iter); // Can't represent unsigned result as an immediate
-#if USE(JSVALUE32)
- linkSlowCase(iter); // Couldn't box result
-#endif
}
JITStubCall stubCall(this, cti_op_urshift);
@@ -330,20 +274,12 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -381,18 +317,9 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();;
@@ -403,13 +330,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -422,18 +343,9 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();;
@@ -444,13 +356,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -463,7 +369,6 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -471,37 +376,14 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -545,20 +427,12 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(LessThan, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -596,18 +470,9 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();
@@ -618,13 +483,7 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -637,18 +496,9 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();
@@ -659,13 +509,7 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -678,7 +522,6 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -686,37 +529,14 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -760,20 +580,12 @@ void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -812,18 +624,9 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();;
@@ -834,13 +637,7 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jlesseq);
@@ -853,18 +650,9 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();;
@@ -875,13 +663,7 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jlesseq);
@@ -894,7 +676,6 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -902,37 +683,14 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -963,25 +721,17 @@ void JIT::emit_op_bitand(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t imm = getConstantOperandImmediateInt(op1);
andPtr(Imm32(imm), regT0);
if (imm >= 0)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), regT0);
-#endif
} else if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t imm = getConstantOperandImmediateInt(op2);
andPtr(Imm32(imm), regT0);
if (imm >= 0)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), regT0);
-#endif
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
andPtr(regT1, regT0);
@@ -1023,13 +773,8 @@ void JIT::emit_op_post_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchAdd32(Overflow, Imm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
-#else
- addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
- signExtend32ToPtr(regT1, regT1);
-#endif
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
@@ -1055,13 +800,8 @@ void JIT::emit_op_post_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchSub32(Zero, Imm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
-#else
- addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
- signExtend32ToPtr(regT1, regT1);
-#endif
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
@@ -1085,13 +825,8 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitPutVirtualRegister(srcDst);
}
@@ -1114,13 +849,8 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchSub32(Zero, Imm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitPutVirtualRegister(srcDst);
}
@@ -1158,22 +888,9 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT2);
-#if USE(JSVALUE64)
addSlowCase(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))));
m_assembler.cdq();
m_assembler.idivl_r(regT2);
-#else
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(emitFastArithDeTagImmediateJumpIfZero(regT2));
-#if CPU(X86) || CPU(X86_64)
- m_assembler.cdq();
- m_assembler.idivl_r(regT2);
- signExtend32ToPtr(regT1, regT1);
-#elif CPU(MIPS)
- m_assembler.div(regT0, regT2);
- m_assembler.mfhi(regT1);
-#endif
-#endif
emitFastArithReTagImmediate(regT1, regT0);
emitPutVirtualRegister(result);
}
@@ -1182,19 +899,9 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
{
unsigned result = currentInstruction[1].u.operand;
-#if USE(JSVALUE64)
linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
-#else
- Jump notImm1 = getSlowCase(iter);
- Jump notImm2 = getSlowCase(iter);
- linkSlowCase(iter);
- emitFastArithReTagImmediate(regT0, regT0);
- emitFastArithReTagImmediate(regT2, regT2);
- notImm1.link(this);
- notImm2.link(this);
-#endif
JITStubCall stubCall(this, cti_op_mod);
stubCall.addArgument(regT0);
stubCall.addArgument(regT2);
@@ -1249,8 +956,6 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
/* ------------------------------ END: OP_MOD ------------------------------ */
-#if USE(JSVALUE64)
-
/* ------------------------------ BEGIN: USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes)
@@ -1543,310 +1248,9 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>
compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types, false, false);
}
-#else // USE(JSVALUE64)
-
-/* ------------------------------ BEGIN: !USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
-
-void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
-{
- Structure* numberStructure = m_globalData->numberStructure.get();
- Jump wasJSNumberCell1;
- Jump wasJSNumberCell2;
-
- emitGetVirtualRegisters(src1, regT0, src2, regT1);
-
- if (types.second().isReusable() && supportsFloatingPoint()) {
- ASSERT(types.second().mightBeNumber());
-
- // Check op2 is a number
- Jump op2imm = emitJumpIfImmediateInteger(regT1);
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT1, src2);
- addSlowCase(checkStructure(regT1, numberStructure));
- }
-
- // (1) In this case src2 is a reusable number cell.
- // Slow case if src1 is not a number type.
- Jump op1imm = emitJumpIfImmediateInteger(regT0);
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT0, src1);
- addSlowCase(checkStructure(regT0, numberStructure));
- }
-
- // (1a) if we get here, src1 is also a number cell
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- Jump loadedDouble = jump();
- // (1b) if we get here, src1 is an immediate
- op1imm.link(this);
- emitFastArithImmToInt(regT0);
- convertInt32ToDouble(regT0, fpRegT0);
- // (1c)
- loadedDouble.link(this);
- if (opcodeID == op_add)
- addDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- else if (opcodeID == op_sub)
- subDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- else {
- ASSERT(opcodeID == op_mul);
- mulDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- }
-
- // Store the result to the JSNumberCell and jump.
- storeDouble(fpRegT0, Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- move(regT1, regT0);
- emitPutVirtualRegister(dst);
- wasJSNumberCell2 = jump();
-
- // (2) This handles cases where src2 is an immediate number.
- // Two slow cases - either src1 isn't an immediate, or the subtract overflows.
- op2imm.link(this);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- } else if (types.first().isReusable() && supportsFloatingPoint()) {
- ASSERT(types.first().mightBeNumber());
-
- // Check op1 is a number
- Jump op1imm = emitJumpIfImmediateInteger(regT0);
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT0, src1);
- addSlowCase(checkStructure(regT0, numberStructure));
- }
-
- // (1) In this case src1 is a reusable number cell.
- // Slow case if src2 is not a number type.
- Jump op2imm = emitJumpIfImmediateInteger(regT1);
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT1, src2);
- addSlowCase(checkStructure(regT1, numberStructure));
- }
-
- // (1a) if we get here, src2 is also a number cell
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
- Jump loadedDouble = jump();
- // (1b) if we get here, src2 is an immediate
- op2imm.link(this);
- emitFastArithImmToInt(regT1);
- convertInt32ToDouble(regT1, fpRegT1);
- // (1c)
- loadedDouble.link(this);
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- if (opcodeID == op_add)
- addDouble(fpRegT1, fpRegT0);
- else if (opcodeID == op_sub)
- subDouble(fpRegT1, fpRegT0);
- else {
- ASSERT(opcodeID == op_mul);
- mulDouble(fpRegT1, fpRegT0);
- }
- storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- emitPutVirtualRegister(dst);
-
- // Store the result to the JSNumberCell and jump.
- storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- emitPutVirtualRegister(dst);
- wasJSNumberCell1 = jump();
-
- // (2) This handles cases where src1 is an immediate number.
- // Two slow cases - either src2 isn't an immediate, or the subtract overflows.
- op1imm.link(this);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
- } else
- emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
-
- if (opcodeID == op_add) {
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchAdd32(Overflow, regT1, regT0));
- } else if (opcodeID == op_sub) {
- addSlowCase(branchSub32(Overflow, regT1, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- } else {
- ASSERT(opcodeID == op_mul);
- // convert eax & edx from JSImmediates to ints, and check if either are zero
- emitFastArithImmToInt(regT1);
- Jump op1Zero = emitFastArithDeTagImmediateJumpIfZero(regT0);
- Jump op2NonZero = branchTest32(NonZero, regT1);
- op1Zero.link(this);
- // if either input is zero, add the two together, and check if the result is < 0.
- // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
- move(regT0, regT2);
- addSlowCase(branchAdd32(Signed, regT1, regT2));
- // Skip the above check if neither input is zero
- op2NonZero.link(this);
- addSlowCase(branchMul32(Overflow, regT1, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- }
- emitPutVirtualRegister(dst);
-
- if (types.second().isReusable() && supportsFloatingPoint())
- wasJSNumberCell2.link(this);
- else if (types.first().isReusable() && supportsFloatingPoint())
- wasJSNumberCell1.link(this);
-}
-
-void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
-{
- linkSlowCase(iter);
- if (types.second().isReusable() && supportsFloatingPoint()) {
- if (!types.first().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src1);
- linkSlowCase(iter);
- }
- if (!types.second().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src2);
- linkSlowCase(iter);
- }
- } else if (types.first().isReusable() && supportsFloatingPoint()) {
- if (!types.first().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src1);
- linkSlowCase(iter);
- }
- if (!types.second().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src2);
- linkSlowCase(iter);
- }
- }
- linkSlowCase(iter);
-
- // additional entry point to handle -0 cases.
- if (opcodeID == op_mul)
- linkSlowCase(iter);
-
- JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul);
- stubCall.addArgument(src1, regT2);
- stubCall.addArgument(src2, regT2);
- stubCall.call(dst);
-}
-
-void JIT::emit_op_add(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
-
- if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- return;
- }
-
- if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
- emitPutVirtualRegister(result);
- } else if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
- emitPutVirtualRegister(result);
- } else {
- compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
- }
-}
-
-void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
- if (!types.first().mightBeNumber() || !types.second().mightBeNumber())
- return;
-
- if (isOperandConstantImmediateInt(op1)) {
- Jump notImm = getSlowCase(iter);
- linkSlowCase(iter);
- sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0);
- notImm.link(this);
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(regT0);
- stubCall.call(result);
- } else if (isOperandConstantImmediateInt(op2)) {
- Jump notImm = getSlowCase(iter);
- linkSlowCase(iter);
- sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0);
- notImm.link(this);
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(regT0);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- } else {
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
- ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
- compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
- }
-}
-
-void JIT::emit_op_mul(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- // For now, only plant a fast int case if the constant operand is greater than zero.
- int32_t value;
- if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
- emitGetVirtualRegister(op2, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- emitPutVirtualRegister(result);
- } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- emitPutVirtualRegister(result);
- } else
- compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
- || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
- JITStubCall stubCall(this, cti_op_mul);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- } else
- compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emit_op_sub(Instruction* currentInstruction)
-{
- compileBinaryArithOp(op_sub, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-#endif // USE(JSVALUE64)
-
/* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp
index 368eab9..fdd0d47 100644
--- a/JavaScriptCore/jit/JITCall.cpp
+++ b/JavaScriptCore/jit/JITCall.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -257,5 +257,5 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITCall32_64.cpp b/JavaScriptCore/jit/JITCall32_64.cpp
index e4005ae..daf5d2d 100644
--- a/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/JavaScriptCore/jit/JITCall32_64.cpp
@@ -108,9 +108,11 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
unsigned dst = currentInstruction[1].u.operand;
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
JITStubCall(this, cti_op_ret_scopeChain).call();
-
+ activationNotCreated.link(this);
+ }
emitLoad(dst, regT1, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
@@ -125,8 +127,11 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
unsigned thisReg = currentInstruction[2].u.operand;
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
JITStubCall(this, cti_op_ret_scopeChain).call();
+ activationNotCreated.link(this);
+ }
emitLoad(result, regT1, regT0);
Jump notJSCell = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
index e2e77db..0fe9929 100644
--- a/JavaScriptCore/jit/JITInlineMethods.h
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -63,7 +63,7 @@ ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterF
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
{
loadPtr(Address(from, entry * sizeof(Register)), to);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
}
@@ -81,7 +81,7 @@ ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst,
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
{
load32(Address(from, entry * sizeof(Register)), to);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
}
@@ -750,7 +750,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
addSlowCase(emitJumpIfNotImmediateNumber(reg));
}
-#if !USE(JSVALUE64)
+#if USE(JSVALUE32_64)
ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
{
subPtr(Imm32(JSImmediate::TagTypeNumber), reg);
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index c81932a..a468c18 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -39,7 +39,7 @@
namespace JSC {
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#define RECORD_JUMP_TARGET(targetOffset) \
do { m_labels[m_bytecodeOffset + (targetOffset)].used(); } while (false)
@@ -337,6 +337,7 @@ void JIT::emit_op_end(Instruction* currentInstruction)
{
if (m_codeBlock->needsFullScopeChain())
JITStubCall(this, cti_op_end).call();
+
ASSERT(returnValueRegister != callFrameRegister);
emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
@@ -360,11 +361,7 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -467,6 +464,15 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
int skip = currentInstruction[3].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
@@ -481,6 +487,15 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1);
emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
@@ -490,10 +505,16 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
{
+ unsigned activation = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ Jump activationCreated = branchTestPtr(NonZero, addressFor(activation));
+ Jump argumentsNotCreated = branchTestPtr(Zero, addressFor(arguments));
+ activationCreated.link(this);
JITStubCall stubCall(this, cti_op_tear_off_activation);
- stubCall.addArgument(currentInstruction[1].u.operand, regT2);
- stubCall.addArgument(unmodifiedArgumentsRegister(currentInstruction[2].u.operand), regT2);
+ stubCall.addArgument(activation, regT2);
+ stubCall.addArgument(unmodifiedArgumentsRegister(arguments), regT2);
stubCall.call();
+ argumentsNotCreated.link(this);
}
void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
@@ -510,9 +531,11 @@ void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
void JIT::emit_op_ret(Instruction* currentInstruction)
{
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
JITStubCall(this, cti_op_ret_scopeChain).call();
-
+ activationNotCreated.link(this);
+ }
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
ASSERT(returnValueRegister != callFrameRegister);
@@ -534,8 +557,11 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
{
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
JITStubCall(this, cti_op_ret_scopeChain).call();
+ activationNotCreated.link(this);
+ }
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
@@ -614,7 +640,15 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
- JITStubCall stubCall(this, cti_op_resolve_base);
+ JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
+ stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_ensure_property_exists);
+ stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -772,12 +806,8 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
not32(regT0);
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);
-#endif
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -865,7 +895,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
emitGetVirtualRegister(base, regT0);
if (!m_codeBlock->isKnownNotImmediate(base))
isNotObject.append(emitJumpIfNotJSCell(regT0));
- if (base != m_codeBlock->thisRegister()) {
+ if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
}
@@ -913,11 +943,7 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
loadPtr(addressFor(it), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
-#if USE(JSVALUE64)
loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2);
-#else
- loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2);
-#endif
emitPutVirtualRegister(dst, regT2);
@@ -1185,16 +1211,14 @@ void JIT::emit_op_enter(Instruction*)
}
-void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+void JIT::emit_op_create_activation(Instruction* currentInstruction)
{
- // Even though CTI doesn't use them, we initialize our constant
- // registers to zap stale pointers, to avoid unnecessarily prolonging
- // object lifetime and increasing GC pressure.
- size_t count = m_codeBlock->m_numVars;
- for (size_t j = 0; j < count; ++j)
- emitInitRegister(j);
-
+ unsigned dst = currentInstruction[1].u.operand;
+
+ Jump activationCreated = branchTestPtr(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+ emitPutVirtualRegister(dst);
+ activationCreated.link(this);
}
void JIT::emit_op_create_arguments(Instruction* currentInstruction)
@@ -1227,6 +1251,23 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
}
+void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
+{
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+ Jump notNull = branchTestPtr(NonZero, regT0);
+ move(ImmPtr(JSValue::encode(jsNull())), regT0);
+ emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
+ Jump setThis = jump();
+ notNull.link(this);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
+ Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ isImmediate.link(this);
+ notAnObject.link(this);
+ setThis.link(this);
+}
+
void JIT::emit_op_get_callee(Instruction* currentInstruction)
{
unsigned result = currentInstruction[1].u.operand;
@@ -1276,6 +1317,14 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_convert_this_strict);
+ stubCall.addArgument(regT0);
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
@@ -1552,13 +1601,25 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto
stubCall.call(dst);
}
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction)
{
int skip = currentInstruction[5].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
+ addSlowCase(checkStructure(regT1, m_globalData->activationStructure.get()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+ activationNotCreated.link(this);
+ }
while (skip--) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
addSlowCase(checkStructure(regT1, m_globalData->activationStructure.get()));
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index ad3b558..c3b7ac2 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -610,6 +610,15 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
int skip = currentInstruction[3].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
@@ -631,6 +640,15 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
emitLoad(value, regT1, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
@@ -644,10 +662,16 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
{
+ unsigned activation = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
+ Jump argumentsNotCreated = branch32(Equal, tagFor(arguments), Imm32(JSValue::EmptyValueTag));
+ activationCreated.link(this);
JITStubCall stubCall(this, cti_op_tear_off_activation);
stubCall.addArgument(currentInstruction[1].u.operand);
stubCall.addArgument(unmodifiedArgumentsRegister(currentInstruction[2].u.operand));
stubCall.call();
+ argumentsNotCreated.link(this);
}
void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
@@ -713,7 +737,15 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
- JITStubCall stubCall(this, cti_op_resolve_base);
+ JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
+ stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_ensure_property_exists);
+ stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1215,7 +1247,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
emitLoad(base, regT1, regT0);
if (!m_codeBlock->isKnownNotImmediate(base))
isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
- if (base != m_codeBlock->thisRegister()) {
+ if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
}
@@ -1467,11 +1499,13 @@ void JIT::emit_op_enter(Instruction*)
emitStore(i, jsUndefined());
}
-void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+void JIT::emit_op_create_activation(Instruction* currentInstruction)
{
- emit_op_enter(currentInstruction);
-
- JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+ unsigned activation = currentInstruction[1].u.operand;
+
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
+ JITStubCall(this, cti_op_push_activation).call(activation);
+ activationCreated.link(this);
}
void JIT::emit_op_create_arguments(Instruction* currentInstruction)
@@ -1528,6 +1562,26 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0);
}
+void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
+{
+ unsigned thisRegister = currentInstruction[1].u.operand;
+
+ emitLoad(thisRegister, regT1, regT0);
+
+ Jump notNull = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
+ emitStore(thisRegister, jsNull());
+ Jump setThis = jump();
+ notNull.link(this);
+ Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ isImmediate.link(this);
+ notAnObject.link(this);
+ setThis.link(this);
+ map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this_strict), thisRegister, regT1, regT0);
+}
+
void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned thisRegister = currentInstruction[1].u.operand;
@@ -1540,6 +1594,17 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
stubCall.call(thisRegister);
}
+void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned thisRegister = currentInstruction[1].u.operand;
+
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_op_convert_this_strict);
+ stubCall.addArgument(regT1, regT0);
+ stubCall.call(thisRegister);
+}
+
void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
{
peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*));
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
index 7c129a5..2edc860 100644
--- a/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -89,7 +89,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitGetVirtualRegisters(base, regT0, property, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
+
// This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
// We check the value as if it was a uint32 against the m_vectorLength - which will always fail if
// number was signed since m_vectorLength is always less than intmax (since the total allocation
@@ -97,9 +97,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
// to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
// extending since it makes it easier to re-tag the value in the slow case.
zeroExtend32ToPtr(regT1, regT1);
-#else
- emitFastArithImmToInt(regT1);
-#endif
+
emitJumpSlowCaseIfNotJSCell(regT0, base);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
@@ -204,12 +202,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
emitGetVirtualRegisters(base, regT0, property, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
// See comment in op_get_by_val.
zeroExtend32ToPtr(regT1, regT1);
-#else
- emitFastArithImmToInt(regT1);
-#endif
emitJumpSlowCaseIfNotJSCell(regT0, base);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
@@ -1103,5 +1097,5 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index f1ec079..8340211 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1065,7 +1065,9 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
return 0; \
} while (0)
#define VM_THROW_EXCEPTION_AT_END() \
- returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
+ do {\
+ returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
+ } while (0)
#define CHECK_FOR_EXCEPTION() \
do { \
@@ -1301,6 +1303,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this)
return JSValue::encode(result);
}
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ JSValue v1 = stackFrame.args[0].jsValue();
+ CallFrame* callFrame = stackFrame.callFrame;
+
+ JSValue result = v1.toStrictThisObject(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValue::encode(result);
+}
+
DEFINE_STUB_FUNCTION(void, op_end)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -1404,7 +1418,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
{
STUB_INIT_STACK_FRAME(stackFrame);
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1413,7 +1427,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
{
STUB_INIT_STACK_FRAME(stackFrame);
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1441,7 +1455,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
@@ -1460,7 +1474,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
@@ -1479,8 +1493,8 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
-
- PutPropertySlot slot;
+
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
@@ -1493,7 +1507,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
@@ -1880,7 +1894,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
- JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier()));
+ bool couldDelete = baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier());
+ JSValue result = jsBoolean(couldDelete);
+ if (!couldDelete && callFrame->codeBlock()->isStrictMode())
+ stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
}
@@ -1906,7 +1924,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
{
STUB_INIT_STACK_FRAME(stackFrame);
-
+
+ ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
}
@@ -2213,10 +2232,18 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
STUB_INIT_STACK_FRAME(stackFrame);
ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
+ JSValue activationValue = stackFrame.args[0].jsValue();
+ if (!activationValue) {
+ if (JSValue v = stackFrame.args[1].jsValue())
+ asArguments(v)->copyRegisters();
+ return;
+ }
JSActivation* activation = asActivation(stackFrame.args[0].jsValue());
activation->copyRegisters();
- if (JSValue v = stackFrame.args[1].jsValue())
- asArguments(v)->setActivation(activation);
+ if (JSValue v = stackFrame.args[1].jsValue()) {
+ if (!stackFrame.callFrame->codeBlock()->isStrictMode())
+ asArguments(v)->setActivation(activation);
+ }
}
DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
@@ -2496,7 +2523,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
} else {
Identifier property(callFrame, subscript.toString(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
}
@@ -2539,7 +2566,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
} else {
Identifier property(callFrame, subscript.toString(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
}
@@ -2670,9 +2697,35 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain()));
+ return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), false));
}
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+ JSValue base = JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), true);
+ if (!base) {
+ stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[0].identifier().ustring());
+ VM_THROW_EXCEPTION();
+ }
+ return JSValue::encode(base);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+ JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
+ JSObject* object = asObject(base);
+ PropertySlot slot(object);
+ ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
+ if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
+ stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().ustring());
+ VM_THROW_EXCEPTION();
+ }
+
+ return JSValue::encode(base);
+}
+
DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2685,6 +2738,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
ASSERT(iter != end);
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
++iter;
ASSERT(iter != end);
@@ -2700,7 +2760,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
}
} while (++iter != end);
- CodeBlock* codeBlock = callFrame->codeBlock();
unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
@@ -3049,6 +3108,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
FunctionExecutable* function = stackFrame.args[0].function();
JSFunction* func = function->make(callFrame, callFrame->scopeChain());
+ ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->r(callFrame->codeBlock()->activationRegister()).jsValue());
/*
The Identifier in a FunctionExpression can be referenced from inside
@@ -3155,6 +3215,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
{
STUB_INIT_STACK_FRAME(stackFrame);
+ ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
CallFrame* callFrame = stackFrame.callFrame;
RegisterFile* registerFile = stackFrame.registerFile;
@@ -3486,19 +3547,22 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
JSObject* baseObj = baseValue.toObject(callFrame); // may throw
JSValue subscript = stackFrame.args[1].jsValue();
- JSValue result;
+ bool result;
uint32_t i;
if (subscript.getUInt32(i))
- result = jsBoolean(baseObj->deleteProperty(callFrame, i));
+ result = baseObj->deleteProperty(callFrame, i);
else {
CHECK_FOR_EXCEPTION();
Identifier property(callFrame, subscript.toString(callFrame));
CHECK_FOR_EXCEPTION();
- result = jsBoolean(baseObj->deleteProperty(callFrame, property));
+ result = baseObj->deleteProperty(callFrame, property);
}
+ if (!result && callFrame->codeBlock()->isStrictMode())
+ stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+
CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
+ return JSValue::encode(jsBoolean(result));
}
DEFINE_STUB_FUNCTION(void, op_put_getter)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index 2b22e6d..b91a074 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -147,7 +147,7 @@ namespace JSC {
struct JITStackFrame {
JITStubArg reserved; // Unused
JITStubArg args[6];
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
void* padding; // Maintain 16-byte stack alignment.
#endif
@@ -296,6 +296,7 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_convert_this_strict(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION);
@@ -337,6 +338,8 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_ensure_property_exists(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_global_dynamic(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION);
diff --git a/JavaScriptCore/jit/JSInterfaceJIT.h b/JavaScriptCore/jit/JSInterfaceJIT.h
index 031bfa8..6453bab 100644
--- a/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -166,7 +166,7 @@ namespace JSC {
inline Address tagFor(unsigned index, RegisterID base = callFrameRegister);
#endif
-#if USE(JSVALUE32) || USE(JSVALUE64)
+#if USE(JSVALUE64)
Jump emitJumpIfImmediateNumber(RegisterID reg);
Jump emitJumpIfNotImmediateNumber(RegisterID reg);
void emitFastArithImmToInt(RegisterID reg);
@@ -273,35 +273,7 @@ namespace JSC {
#endif
-#if USE(JSVALUE32)
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
- {
- loadPtr(addressFor(virtualRegisterIndex), dst);
- return branchTest32(NonZero, dst, Imm32(JSImmediate::TagMask));
- }
-
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
- {
- loadPtr(addressFor(virtualRegisterIndex), dst);
- Jump result = branchTest32(Zero, dst, Imm32(JSImmediate::TagTypeNumber));
- rshift32(Imm32(JSImmediate::IntegerPayloadShift), dst);
- return result;
- }
-
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned, FPRegisterID, RegisterID)
- {
- ASSERT_NOT_REACHED();
- return jump();
- }
-
- ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID reg)
- {
- rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);
- }
-
-#endif
-
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
diff --git a/JavaScriptCore/jit/SpecializedThunkJIT.h b/JavaScriptCore/jit/SpecializedThunkJIT.h
index 57515fb..5c593d9 100644
--- a/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -96,14 +96,10 @@ namespace JSC {
#if USE(JSVALUE64)
moveDoubleToPtr(src, regT0);
subPtr(tagTypeNumberRegister, regT0);
-#elif USE(JSVALUE32_64)
+#else
storeDouble(src, Address(stackPointerRegister, -(int)sizeof(double)));
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
-#else
- UNUSED_PARAM(src);
- ASSERT_NOT_REACHED();
- m_failures.append(jump());
#endif
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
ret();
@@ -144,13 +140,8 @@ namespace JSC {
{
#if USE(JSVALUE64)
orPtr(tagTypeNumberRegister, regT0);
-#elif USE(JSVALUE32_64)
- move(Imm32(JSValue::Int32Tag), regT1);
#else
- signExtend32ToPtr(regT0, regT0);
- // If we can't tag the result, give up and jump to the slow case
- m_failures.append(branchAddPtr(Overflow, regT0, regT0));
- addPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
+ move(Imm32(JSValue::Int32Tag), regT1);
#endif
}
diff --git a/JavaScriptCore/jit/ThunkGenerators.cpp b/JavaScriptCore/jit/ThunkGenerators.cpp
index 4c7a354..9b40f12 100644
--- a/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -92,7 +92,6 @@ MacroAssemblerCodePtr fromCharCodeThunkGenerator(JSGlobalData* globalData, Execu
MacroAssemblerCodePtr sqrtThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
{
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
SpecializedThunkJIT jit(1, globalData, pool);
if (!jit.supportsFloatingPointSqrt())
return globalData->jitStubs->ctiNativeCall();
@@ -101,10 +100,6 @@ MacroAssemblerCodePtr sqrtThunkGenerator(JSGlobalData* globalData, ExecutablePoo
jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
return jit.finalize(globalData->jitStubs->ctiNativeCall());
-#else
- UNUSED_PARAM(pool);
- return globalData->jitStubs->ctiNativeCall();
-#endif
}
static const double oneConstant = 1.0;
@@ -112,7 +107,6 @@ static const double negativeHalfConstant = -0.5;
MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
{
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
SpecializedThunkJIT jit(2, globalData, pool);
if (!jit.supportsFloatingPoint())
return globalData->jitStubs->ctiNativeCall();
@@ -161,10 +155,6 @@ MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool
jit.appendFailure(nonIntExponent);
return jit.finalize(globalData->jitStubs->ctiNativeCall());
-#else
- UNUSED_PARAM(pool);
- return globalData->jitStubs->ctiNativeCall();
-#endif
}
}
diff --git a/JavaScriptCore/parser/ASTBuilder.h b/JavaScriptCore/parser/ASTBuilder.h
index 40023f8..9a68144 100644
--- a/JavaScriptCore/parser/ASTBuilder.h
+++ b/JavaScriptCore/parser/ASTBuilder.h
@@ -249,10 +249,10 @@ public:
return result;
}
- FunctionBodyNode* createFunctionBody()
+ FunctionBodyNode* createFunctionBody(bool inStrictContext)
{
usesClosures();
- return FunctionBodyNode::create(m_globalData);
+ return FunctionBodyNode::create(m_globalData, inStrictContext);
}
template <bool> PropertyNode* createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
@@ -578,6 +578,9 @@ public:
const Identifier& getName(Property property) { return property->name(); }
PropertyNode::Type getType(Property property) { return property->type(); }
+
+ bool isResolve(ExpressionNode* expr) { return expr->isResolveNode(); }
+
private:
struct Scope {
Scope(JSGlobalData* globalData)
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp
index 0e526ac..0338210 100644
--- a/JavaScriptCore/parser/JSParser.cpp
+++ b/JavaScriptCore/parser/JSParser.cpp
@@ -29,6 +29,7 @@
using namespace JSC;
+#include "CodeBlock.h"
#include "JSGlobalData.h"
#include "NodeInfo.h"
#include "ASTBuilder.h"
@@ -42,6 +43,8 @@ namespace JSC {
#define fail() do { m_error = true; return 0; } while (0)
#define failIfFalse(cond) do { if (!(cond)) fail(); } while (0)
#define failIfTrue(cond) do { if ((cond)) fail(); } while (0)
+#define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0)
+#define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0)
#define consumeOrFail(tokenType) do { if (!consume(tokenType)) fail(); } while (0)
#define matchOrFail(tokenType) do { if (!match(tokenType)) fail(); } while (0)
#define failIfStackOverflow() do { failIfFalse(canRecurse()); } while (0)
@@ -67,8 +70,8 @@ static const ptrdiff_t kMaxParserStackUsage = 128 * sizeof(void*) * 1024;
class JSParser {
public:
- JSParser(Lexer*, JSGlobalData*, FunctionParameters*, SourceProvider*);
- bool parseProgram();
+ JSParser(Lexer*, JSGlobalData*, FunctionParameters*, bool isStrictContext, bool isFunction, SourceProvider*);
+ bool parseProgram(JSGlobalObject*);
private:
struct AllowInOverride {
AllowInOverride(JSParser* parser)
@@ -90,7 +93,7 @@ private:
m_lastLine = m_token.m_info.line;
m_lastTokenEnd = m_token.m_info.endOffset;
m_lexer->setLastLineNumber(m_lastLine);
- m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType);
+ m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType, strictMode());
m_tokenCount++;
}
@@ -121,9 +124,23 @@ private:
{
return m_token.m_info.endOffset;
}
-
- template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
- template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&);
+
+ void startLoop() { currentScope()->startLoop(); }
+ void endLoop() { currentScope()->endLoop(); }
+ void startSwitch() { currentScope()->startSwitch(); }
+ void endSwitch() { currentScope()->endSwitch(); }
+ void setStrictMode() { currentScope()->setStrictMode(); }
+ bool strictMode() { return currentScope()->strictMode(); }
+ bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
+ bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
+ bool breakIsValid() { return currentScope()->breakIsValid(); }
+ void pushLabel(const Identifier* label) { currentScope()->pushLabel(label); }
+ void popLabel() { currentScope()->popLabel(); }
+ bool hasLabel(const Identifier* label) { return currentScope()->hasLabel(label); }
+
+ enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
+ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
+ template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive);
template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
@@ -199,32 +216,118 @@ private:
int m_assignmentCount;
int m_nonLHSCount;
bool m_syntaxAlreadyValidated;
+ int m_statementDepth;
+ int m_nonTrivialExpressionCount;
+ const Identifier* m_lastIdentifier;
+
+ struct DepthManager {
+ DepthManager(int* depth)
+ : m_originalDepth(*depth)
+ , m_depth(depth)
+ {
+ }
+
+ ~DepthManager()
+ {
+ *m_depth = m_originalDepth;
+ }
+
+ private:
+ int m_originalDepth;
+ int* m_depth;
+ };
struct Scope {
- Scope()
- : m_usesEval(false)
+ Scope(JSGlobalData* globalData, bool isFunction, bool strictMode)
+ : m_globalData(globalData)
+ , m_usesEval(false)
, m_needsFullActivation(false)
, m_allowsNewDecls(true)
+ , m_strictMode(strictMode)
+ , m_isFunction(isFunction)
+ , m_isValidStrictMode(true)
+ , m_loopDepth(0)
+ , m_switchDepth(0)
+ , m_labels(0)
+ {
+ }
+
+ void startSwitch() { m_switchDepth++; }
+ void endSwitch() { m_switchDepth--; }
+ void startLoop() { m_loopDepth++; }
+ void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
+ bool inLoop() { return !!m_loopDepth; }
+ bool breakIsValid() { return m_loopDepth || m_switchDepth; }
+
+ void pushLabel(const Identifier* label)
+ {
+ if (!m_labels)
+ m_labels = new LabelStack;
+ m_labels->append(label->impl());
+ }
+
+ void popLabel()
{
+ ASSERT(m_labels);
+ ASSERT(m_labels->size());
+ m_labels->removeLast();
}
+
+ bool hasLabel(const Identifier* label)
+ {
+ if (!m_labels)
+ return false;
+ for (int i = m_labels->size(); i > 0; i--) {
+ if (m_labels->at(i - 1) == label->impl())
+ return true;
+ }
+ return false;
+ }
+
+ void setIsFunction() { m_isFunction = true; }
+ bool isFunction() { return m_isFunction; }
- void declareVariable(const Identifier* ident)
+ bool declareVariable(const Identifier* ident)
{
+ bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
+ m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
m_declaredVariables.add(ident->ustring().impl());
+ return isValidStrictMode;
+ }
+
+ void declareWrite(const Identifier* ident)
+ {
+ ASSERT(m_strictMode);
+ m_writtenVariables.add(ident->impl());
+ }
+
+ bool deleteProperty(const Identifier* ident)
+ {
+ if (m_declaredVariables.contains(ident->impl()))
+ return false;
+ m_deletedVariables.add(ident->impl());
+ return true;
}
void preventNewDecls() { m_allowsNewDecls = false; }
bool allowsNewDecls() const { return m_allowsNewDecls; }
+ bool declareParameter(const Identifier* ident)
+ {
+ bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).second && m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
+ m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
+ return isValidStrictMode;
+ }
+
void useVariable(const Identifier* ident, bool isEval)
{
m_usesEval |= isEval;
m_usedVariables.add(ident->ustring().impl());
}
- void needsFullActivation() { m_needsFullActivation = true; }
+ void setNeedsFullActivation() { m_needsFullActivation = true; }
- void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
+ bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
{
if (nestedScope->m_usesEval)
m_usesEval = true;
@@ -236,6 +339,45 @@ private:
if (shouldTrackClosedVariables)
m_closedVariables.add(*ptr);
}
+ if (nestedScope->m_writtenVariables.size()) {
+ IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
+ for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
+ if (nestedScope->m_declaredVariables.contains(*ptr))
+ continue;
+ m_writtenVariables.add(*ptr);
+ }
+ }
+ if (nestedScope->m_deletedVariables.size()) {
+ IdentifierSet::iterator end = nestedScope->m_deletedVariables.end();
+ for (IdentifierSet::iterator ptr = nestedScope->m_deletedVariables.begin(); ptr != end; ++ptr) {
+ if (nestedScope->m_declaredVariables.contains(*ptr))
+ return false;
+ if (m_declaredVariables.contains(*ptr))
+ return false;
+ m_deletedVariables.add(*ptr);
+ }
+ }
+ return true;
+ }
+
+ void getUncapturedWrittenVariables(IdentifierSet& writtenVariables)
+ {
+ IdentifierSet::iterator end = m_writtenVariables.end();
+ for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
+ if (!m_declaredVariables.contains(*ptr))
+ writtenVariables.add(*ptr);
+ }
+ }
+
+ bool getDeletedVariables(IdentifierSet& deletedVariables)
+ {
+ IdentifierSet::iterator end = m_deletedVariables.end();
+ for (IdentifierSet::iterator ptr = m_deletedVariables.begin(); ptr != end; ++ptr) {
+ if (m_declaredVariables.contains(*ptr))
+ return false;
+ }
+ deletedVariables.swap(m_deletedVariables);
+ return true;
}
void getCapturedVariables(IdentifierSet& capturedVariables)
@@ -250,13 +392,27 @@ private:
capturedVariables.add(*ptr);
}
}
+ void setStrictMode() { m_strictMode = true; }
+ bool strictMode() const { return m_strictMode; }
+ bool isValidStrictMode() const { return m_isValidStrictMode; }
+
private:
- bool m_usesEval;
- bool m_needsFullActivation;
- bool m_allowsNewDecls;
+ JSGlobalData* m_globalData;
+ bool m_usesEval : 1;
+ bool m_needsFullActivation : 1;
+ bool m_allowsNewDecls : 1;
+ bool m_strictMode : 1;
+ bool m_isFunction : 1;
+ bool m_isValidStrictMode : 1;
+ int m_loopDepth;
+ int m_switchDepth;
+ typedef Vector<StringImpl*, 2> LabelStack;
+ LabelStack* m_labels;
IdentifierSet m_declaredVariables;
IdentifierSet m_usedVariables;
IdentifierSet m_closedVariables;
+ IdentifierSet m_writtenVariables;
+ IdentifierSet m_deletedVariables;
};
typedef Vector<Scope, 10> ScopeStack;
@@ -281,19 +437,26 @@ private:
ScopeRef pushScope()
{
- m_scopeStack.append(Scope());
+ bool isFunction = false;
+ bool isStrict = false;
+ if (!m_scopeStack.isEmpty()) {
+ isStrict = m_scopeStack.last().strictMode();
+ isFunction = m_scopeStack.last().isFunction();
+ }
+ m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
return currentScope();
}
- void popScope(ScopeRef scope, bool shouldTrackClosedVariables)
+ bool popScope(ScopeRef scope, bool shouldTrackClosedVariables)
{
ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
ASSERT(m_scopeStack.size() > 1);
- m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
+ bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
m_scopeStack.removeLast();
+ return result;
}
- void declareVariable(const Identifier* ident)
+ bool declareVariable(const Identifier* ident)
{
unsigned i = m_scopeStack.size() - 1;
ASSERT(i < m_scopeStack.size());
@@ -301,19 +464,32 @@ private:
i--;
ASSERT(i < m_scopeStack.size());
}
- m_scopeStack[i].declareVariable(ident);
+ return m_scopeStack[i].declareVariable(ident);
+ }
+
+ void declareWrite(const Identifier* ident)
+ {
+ if (!m_syntaxAlreadyValidated)
+ m_scopeStack.last().declareWrite(ident);
}
+ bool deleteProperty(const Identifier* ident)
+ {
+ if (!m_syntaxAlreadyValidated)
+ return m_scopeStack.last().deleteProperty(ident);
+ return true;
+ }
+
ScopeStack m_scopeStack;
};
-int jsParse(JSGlobalData* globalData, FunctionParameters* parameters, const SourceCode* source)
+int jsParse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, const SourceCode* source)
{
- JSParser parser(globalData->lexer, globalData, parameters, source->provider());
- return parser.parseProgram();
+ JSParser parser(lexicalGlobalObject->globalData()->lexer, lexicalGlobalObject->globalData(), parameters, strictness == JSParseStrict, parserMode == JSParseFunctionCode, source->provider());
+ return parser.parseProgram(lexicalGlobalObject);
}
-JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, SourceProvider* provider)
+JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, bool inStrictContext, bool isFunction, SourceProvider* provider)
: m_lexer(lexer)
, m_endAddress(0)
, m_error(false)
@@ -325,28 +501,48 @@ JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* p
, m_assignmentCount(0)
, m_nonLHSCount(0)
, m_syntaxAlreadyValidated(provider->isValid())
+ , m_statementDepth(0)
+ , m_nonTrivialExpressionCount(0)
+ , m_lastIdentifier(0)
{
m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage;
- next();
- m_lexer->setLastLineNumber(tokenLine());
ScopeRef scope = pushScope();
+ if (isFunction)
+ scope->setIsFunction();
+ if (inStrictContext)
+ scope->setStrictMode();
if (parameters) {
for (unsigned i = 0; i < parameters->size(); i++)
- scope->declareVariable(&parameters->at(i));
+ scope->declareParameter(&parameters->at(i));
}
+ next();
+ m_lexer->setLastLineNumber(tokenLine());
}
-bool JSParser::parseProgram()
+bool JSParser::parseProgram(JSGlobalObject* lexicalGlobalObject)
{
ASTBuilder context(m_globalData, m_lexer);
+ if (m_lexer->isReparsing())
+ m_statementDepth--;
ScopeRef scope = currentScope();
- SourceElements* sourceElements = parseSourceElements<ASTBuilder>(context);
+ SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context);
if (!sourceElements || !consume(EOFTOK))
return true;
+ if (!m_syntaxAlreadyValidated) {
+ IdentifierSet deletedVariables;
+ if (!scope->getDeletedVariables(deletedVariables))
+ return true;
+ IdentifierSet::const_iterator end = deletedVariables.end();
+ SymbolTable& globalEnvRecord = lexicalGlobalObject->symbolTable();
+ for (IdentifierSet::const_iterator ptr = deletedVariables.begin(); ptr != end; ++ptr) {
+ if (!globalEnvRecord.get(*ptr).isNull())
+ return true;
+ }
+ }
IdentifierSet capturedVariables;
scope->getCapturedVariables(capturedVariables);
- m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features(),
- m_lastLine, context.numConstants(), capturedVariables);
+ m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features() | (scope->strictMode() ? StrictModeFeature : 0),
+ m_lastLine, context.numConstants(), capturedVariables);
return false;
}
@@ -355,11 +551,30 @@ bool JSParser::allowAutomaticSemicolon()
return match(CLOSEBRACE) || match(EOFTOK) || m_lexer->prevTerminator();
}
-template <class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context)
+template <JSParser::SourceElementsMode mode, class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context)
{
TreeSourceElements sourceElements = context.createSourceElements();
- while (TreeStatement statement = parseStatement(context))
+ bool seenNonDirective = false;
+ const Identifier* directive = 0;
+ unsigned startOffset = m_token.m_info.startOffset;
+ bool hasSetStrict = false;
+ while (TreeStatement statement = parseStatement(context, directive)) {
+ if (mode == CheckForStrictMode && !seenNonDirective) {
+ if (directive) {
+ if (!hasSetStrict && m_globalData->propertyNames->useStrictIdentifier == *directive) {
+ setStrictMode();
+ hasSetStrict = true;
+ failIfFalse(isValidStrictMode());
+ m_lexer->setOffset(startOffset);
+ next();
+ failIfTrue(m_error);
+ continue;
+ }
+ } else
+ seenNonDirective = true;
+ }
context.appendStatement(sourceElements, statement);
+ }
if (m_error)
fail();
@@ -399,7 +614,10 @@ template <class TreeBuilder> TreeStatement JSParser::parseDoWhileStatement(TreeB
ASSERT(match(DO));
int startLine = tokenLine();
next();
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ startLoop();
+ TreeStatement statement = parseStatement(context, unused);
+ endLoop();
failIfFalse(statement);
int endLine = tokenLine();
consumeOrFail(WHILE);
@@ -422,7 +640,10 @@ template <class TreeBuilder> TreeStatement JSParser::parseWhileStatement(TreeBui
failIfFalse(expr);
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ startLoop();
+ TreeStatement statement = parseStatement(context, unused);
+ endLoop();
failIfFalse(statement);
return context.createWhileStatement(expr, statement, startLine, endLine);
}
@@ -441,7 +662,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr
lastIdent = name;
next();
bool hasInitializer = match(EQUAL);
- declareVariable(name);
+ failIfFalseIfStrict(declareVariable(name));
context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
if (hasInitializer) {
int varDivot = tokenStart() + 1;
@@ -465,6 +686,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr
template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationList(TreeBuilder& context)
{
+ failIfTrue(strictMode());
TreeConstDeclList constDecls = 0;
TreeConstDeclList tail = 0;
do {
@@ -532,7 +754,10 @@ template <class TreeBuilder> TreeStatement JSParser::parseForStatement(TreeBuild
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ startLoop();
+ TreeStatement statement = parseStatement(context, unused);
+ endLoop();
failIfFalse(statement);
return context.createForInLoop(forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
@@ -566,7 +791,10 @@ template <class TreeBuilder> TreeStatement JSParser::parseForStatement(TreeBuild
}
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ startLoop();
+ TreeStatement statement = parseStatement(context, unused);
+ endLoop();
failIfFalse(statement);
return context.createForLoop(decls, condition, increment, statement, hasDeclaration, startLine, endLine);
}
@@ -579,7 +807,10 @@ template <class TreeBuilder> TreeStatement JSParser::parseForStatement(TreeBuild
int exprEnd = lastTokenEnd();
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ startLoop();
+ TreeStatement statement = parseStatement(context, unused);
+ endLoop();
failIfFalse(statement);
return context.createForInLoop(decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
@@ -594,10 +825,13 @@ template <class TreeBuilder> TreeStatement JSParser::parseBreakStatement(TreeBui
int endLine = tokenLine();
next();
- if (autoSemiColon())
+ if (autoSemiColon()) {
+ failIfFalseIfStrict(breakIsValid());
return context.createBreakStatement(startCol, endCol, startLine, endLine);
+ }
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
+ failIfFalseIfStrict(hasLabel(ident));
endCol = tokenEnd();
endLine = tokenLine();
next();
@@ -614,10 +848,13 @@ template <class TreeBuilder> TreeStatement JSParser::parseContinueStatement(Tree
int endLine = tokenLine();
next();
- if (autoSemiColon())
+ if (autoSemiColon()) {
+ failIfFalseIfStrict(breakIsValid());
return context.createContinueStatement(startCol, endCol, startLine, endLine);
+ }
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
+ failIfFalseIfStrict(hasLabel(ident));
endCol = tokenEnd();
endLine = tokenLine();
next();
@@ -628,6 +865,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseContinueStatement(Tree
template <class TreeBuilder> TreeStatement JSParser::parseReturnStatement(TreeBuilder& context)
{
ASSERT(match(RETURN));
+ failIfFalseIfStrict(currentScope()->isFunction());
int startLine = tokenLine();
int endLine = startLine;
int start = tokenStart();
@@ -655,6 +893,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseThrowStatement(TreeBui
int eStart = tokenStart();
int startLine = tokenLine();
next();
+
+ failIfTrue(autoSemiColon());
TreeExpression expr = parseExpression(context);
failIfFalse(expr);
@@ -668,7 +908,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseThrowStatement(TreeBui
template <class TreeBuilder> TreeStatement JSParser::parseWithStatement(TreeBuilder& context)
{
ASSERT(match(WITH));
- currentScope()->needsFullActivation();
+ failIfTrue(strictMode());
+ currentScope()->setNeedsFullActivation();
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -679,8 +920,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseWithStatement(TreeBuil
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
-
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ TreeStatement statement = parseStatement(context, unused);
failIfFalse(statement);
return context.createWithStatement(expr, statement, start, end, startLine, endLine);
@@ -697,7 +938,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseSwitchStatement(TreeBu
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
consumeOrFail(OPENBRACE);
-
+ startSwitch();
TreeClauseList firstClauses = parseSwitchClauses(context);
failIfTrue(m_error);
@@ -706,6 +947,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseSwitchStatement(TreeBu
TreeClauseList secondClauses = parseSwitchClauses(context);
failIfTrue(m_error);
+ endSwitch();
consumeOrFail(CLOSEBRACE);
return context.createSwitchStatement(expr, firstClauses, defaultClause, secondClauses, startLine, endLine);
@@ -720,7 +962,7 @@ template <class TreeBuilder> TreeClauseList JSParser::parseSwitchClauses(TreeBui
TreeExpression condition = parseExpression(context);
failIfFalse(condition);
consumeOrFail(COLON);
- TreeSourceElements statements = parseSourceElements(context);
+ TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
failIfFalse(statements);
TreeClause clause = context.createClause(condition, statements);
TreeClauseList clauseList = context.createClauseList(clause);
@@ -731,7 +973,7 @@ template <class TreeBuilder> TreeClauseList JSParser::parseSwitchClauses(TreeBui
TreeExpression condition = parseExpression(context);
failIfFalse(condition);
consumeOrFail(COLON);
- TreeSourceElements statements = parseSourceElements(context);
+ TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
failIfFalse(statements);
clause = context.createClause(condition, statements);
tail = context.createClauseList(tail, clause);
@@ -745,7 +987,7 @@ template <class TreeBuilder> TreeClause JSParser::parseSwitchDefaultClause(TreeB
return 0;
next();
consumeOrFail(COLON);
- TreeSourceElements statements = parseSourceElements(context);
+ TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
failIfFalse(statements);
return context.createClause(0, statements);
}
@@ -767,14 +1009,14 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild
int lastLine = m_lastLine;
if (match(CATCH)) {
- currentScope()->needsFullActivation();
+ currentScope()->setNeedsFullActivation();
next();
consumeOrFail(OPENPAREN);
matchOrFail(IDENT);
ident = m_token.m_data.ident;
next();
ScopeRef catchScope = pushScope();
- catchScope->declareVariable(ident);
+ failIfFalseIfStrict(catchScope->declareVariable(ident));
catchScope->preventNewDecls();
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
@@ -782,7 +1024,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild
catchBlock = parseBlockStatement(context);
failIfFalse(catchBlock);
catchHasEval = initialEvalCount != context.evalCount();
- popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
+ failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo));
}
if (match(FINALLY)) {
@@ -816,15 +1058,19 @@ template <class TreeBuilder> TreeStatement JSParser::parseBlockStatement(TreeBui
next();
return context.createBlockStatement(0, start, m_lastLine);
}
- TreeSourceElements subtree = parseSourceElements(context);
+ TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context);
failIfFalse(subtree);
matchOrFail(CLOSEBRACE);
next();
return context.createBlockStatement(subtree, start, m_lastLine);
}
-template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context)
+template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context, const Identifier*& directive)
{
+ DepthManager statementDepth(&m_statementDepth);
+ m_statementDepth++;
+ directive = 0;
+ int nonTrivialExpressionCount = 0;
failIfStackOverflow();
switch (m_token.m_type) {
case OPENBRACE:
@@ -834,6 +1080,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder&
case CONSTTOKEN:
return parseConstDeclaration(context);
case FUNCTION:
+ failIfFalseIfStrict(m_statementDepth == 1);
return parseFunctionDeclaration(context);
case SEMICOLON:
next();
@@ -870,8 +1117,14 @@ template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder&
return 0;
case IDENT:
return parseExpressionOrLabelStatement(context);
+ case STRING:
+ directive = m_token.m_data.ident;
+ nonTrivialExpressionCount = m_nonTrivialExpressionCount;
default:
- return parseExpressionStatement(context);
+ TreeStatement exprStatement = parseExpressionStatement(context);
+ if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
+ directive = 0;
+ return exprStatement;
}
}
@@ -879,7 +1132,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
{
matchOrFail(IDENT);
usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident;
- declareVariable(m_token.m_data.ident);
+ failIfFalseIfStrict(declareParameter(m_token.m_data.ident));
TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
TreeFormalParameterList tail = list;
next();
@@ -887,7 +1140,8 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
next();
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
- declareVariable(ident);
+ usesArguments |= m_globalData->propertyNames->arguments == *m_token.m_data.ident;
+ failIfFalseIfStrict(declareParameter(ident));
next();
usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident;
tail = context.createFormalParameterList(tail, *ident);
@@ -898,20 +1152,23 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame
template <class TreeBuilder> TreeFunctionBody JSParser::parseFunctionBody(TreeBuilder& context)
{
if (match(CLOSEBRACE))
- return context.createFunctionBody();
+ return context.createFunctionBody(strictMode());
+ DepthManager statementDepth(&m_statementDepth);
+ m_statementDepth = 0;
typename TreeBuilder::FunctionBodyBuilder bodyBuilder(m_globalData, m_lexer);
- failIfFalse(parseSourceElements(bodyBuilder));
- return context.createFunctionBody();
+ failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
+ return context.createFunctionBody(strictMode());
}
template <JSParser::FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
{
ScopeRef functionScope = pushScope();
+ functionScope->setIsFunction();
if (match(IDENT)) {
name = m_token.m_data.ident;
next();
if (!nameIsInContainingScope)
- functionScope->declareVariable(name);
+ failIfFalseIfStrict(functionScope->declareVariable(name));
} else if (requirements == FunctionNeedsName)
return false;
consumeOrFail(OPENPAREN);
@@ -931,7 +1188,11 @@ template <JSParser::FunctionRequirements requirements, bool nameIsInContainingSc
failIfFalse(body);
if (usesArguments)
context.setUsesArguments(body);
- popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
+ if (functionScope->strictMode() && name) {
+ failIfTrue(m_globalData->propertyNames->arguments == *name);
+ failIfTrue(m_globalData->propertyNames->eval == *name);
+ }
+ failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
matchOrFail(CLOSEBRACE);
closeBracePos = m_token.m_data.intValue;
next();
@@ -950,7 +1211,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseFunctionDeclaration(Tr
int bodyStartLine = 0;
failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
failIfFalse(name);
- declareVariable(name);
+ failIfFalseIfStrict(declareVariable(name));
return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
@@ -973,7 +1234,12 @@ template <class TreeBuilder> TreeStatement JSParser::parseExpressionOrLabelState
failIfFalse(currentToken + 1 == m_tokenCount);
int end = tokenEnd();
consumeOrFail(COLON);
- TreeStatement statement = parseStatement(context);
+ const Identifier* unused = 0;
+ if (strictMode() && !m_syntaxAlreadyValidated)
+ pushLabel(ident);
+ TreeStatement statement = parseStatement(context, unused);
+ if (strictMode() && !m_syntaxAlreadyValidated)
+ popLabel();
failIfFalse(statement);
return context.createLabelStatement(ident, statement, start, end);
}
@@ -1001,7 +1267,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseIfStatement(TreeBuilde
int end = tokenLine();
consumeOrFail(CLOSEPAREN);
- TreeStatement trueBlock = parseStatement(context);
+ const Identifier* unused = 0;
+ TreeStatement trueBlock = parseStatement(context, unused);
failIfFalse(trueBlock);
if (!match(ELSE))
@@ -1014,7 +1281,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseIfStatement(TreeBuilde
do {
next();
if (!match(IF)) {
- TreeStatement block = parseStatement(context);
+ const Identifier* unused = 0;
+ TreeStatement block = parseStatement(context, unused);
failIfFalse(block);
statementStack.append(block);
trailingElse = true;
@@ -1029,8 +1297,8 @@ template <class TreeBuilder> TreeStatement JSParser::parseIfStatement(TreeBuilde
failIfFalse(innerCondition);
int innerEnd = tokenLine();
consumeOrFail(CLOSEPAREN);
-
- TreeStatement innerTrueBlock = parseStatement(context);
+ const Identifier* unused = 0;
+ TreeStatement innerTrueBlock = parseStatement(context, unused);
failIfFalse(innerTrueBlock);
exprStack.append(innerCondition);
posStack.append(make_pair(innerStart, innerEnd));
@@ -1070,6 +1338,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseExpression(TreeBuilde
if (!match(COMMA))
return node;
next();
+ m_nonTrivialExpressionCount++;
m_nonLHSCount++;
TreeExpression right = parseAssignmentExpression(context);
failIfFalse(right);
@@ -1115,11 +1384,17 @@ template <typename TreeBuilder> TreeExpression JSParser::parseAssignmentExpressi
default:
goto end;
}
+ m_nonTrivialExpressionCount++;
hadAssignment = true;
context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op);
start = tokenStart();
m_assignmentCount++;
next();
+ if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
+ failIfTrueIfStrict(m_globalData->propertyNames->eval == *m_lastIdentifier);
+ declareWrite(m_lastIdentifier);
+ m_lastIdentifier = 0;
+ }
lhs = parseConditionalExpression(context);
failIfFalse(lhs);
if (initialNonLHSCount != m_nonLHSCount)
@@ -1144,6 +1419,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseConditionalExpression
failIfFalse(cond);
if (!match(QUESTION))
return cond;
+ m_nonTrivialExpressionCount++;
m_nonLHSCount++;
next();
TreeExpression lhs = parseAssignmentExpression(context);
@@ -1181,6 +1457,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(Tree
int precedence = isBinaryOperator(m_token.m_type);
if (!precedence)
break;
+ m_nonTrivialExpressionCount++;
m_nonLHSCount++;
int operatorToken = m_token.m_type;
next();
@@ -1196,7 +1473,6 @@ template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(Tree
}
context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
}
-
while (operatorStackDepth) {
ASSERT(operandStackDepth > 1);
@@ -1327,6 +1603,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseStrictObjectLiteral(T
if (!m_syntaxAlreadyValidated) {
std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property));
if (!propertyEntryIter.second) {
+ failIfTrue(strictMode());
if ((context.getType(property) & propertyEntryIter.first->second) != PropertyNode::Constant) {
// Can't have multiple getters or setters with the same name, nor can we define
// a property as both an accessor and a constant value
@@ -1389,6 +1666,8 @@ template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(Tre
{
switch (m_token.m_type) {
case OPENBRACE:
+ if (strictMode())
+ return parseStrictObjectLiteral(context);
return parseObjectLiteral(context);
case OPENBRACKET:
return parseArrayLiteral(context);
@@ -1410,6 +1689,7 @@ template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(Tre
const Identifier* ident = m_token.m_data.ident;
next();
currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
+ m_lastIdentifier = ident;
return context.createResolve(ident, start);
}
case STRING: {
@@ -1485,6 +1765,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
next();
newCount++;
}
+
if (match(FUNCTION)) {
const Identifier* name = &m_globalData->propertyNames->nullIdentifier;
TreeFormalParameterList parameters = 0;
@@ -1502,6 +1783,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
while (true) {
switch (m_token.m_type) {
case OPENBRACKET: {
+ m_nonTrivialExpressionCount++;
int expressionEnd = lastTokenEnd();
next();
int nonLHSCount = m_nonLHSCount;
@@ -1515,6 +1797,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
break;
}
case OPENPAREN: {
+ m_nonTrivialExpressionCount++;
if (newCount) {
newCount--;
if (match(OPENPAREN)) {
@@ -1535,6 +1818,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
break;
}
case DOT: {
+ m_nonTrivialExpressionCount++;
int expressionEnd = lastTokenEnd();
next(Lexer::IgnoreReservedWords);
matchOrFail(IDENT);
@@ -1556,25 +1840,62 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB
{
AllowInOverride allowInOverride(this);
int tokenStackDepth = 0;
+ bool modifiesExpr = false;
+ bool requiresLExpr = false;
while (isUnaryOp(m_token.m_type)) {
+ if (strictMode()) {
+ switch (m_token.m_type) {
+ case PLUSPLUS:
+ case MINUSMINUS:
+ case AUTOPLUSPLUS:
+ case AUTOMINUSMINUS:
+ failIfTrue(requiresLExpr);
+ modifiesExpr = true;
+ requiresLExpr = true;
+ break;
+ case DELETETOKEN:
+ failIfTrue(requiresLExpr);
+ requiresLExpr = true;
+ break;
+ default:
+ failIfTrue(requiresLExpr);
+ break;
+ }
+ }
m_nonLHSCount++;
context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
next();
+ m_nonTrivialExpressionCount++;
}
int subExprStart = tokenStart();
TreeExpression expr = parseMemberExpression(context);
failIfFalse(expr);
+ bool isEvalOrArguments = false;
+ if (strictMode() && !m_syntaxAlreadyValidated) {
+ if (context.isResolve(expr)) {
+ isEvalOrArguments = m_globalData->propertyNames->eval == *m_lastIdentifier;
+ if (!isEvalOrArguments && currentScope()->isFunction())
+ isEvalOrArguments = m_globalData->propertyNames->arguments == *m_lastIdentifier;
+ }
+ }
+ failIfTrueIfStrict(isEvalOrArguments && modifiesExpr);
switch (m_token.m_type) {
case PLUSPLUS:
+ m_nonTrivialExpressionCount++;
m_nonLHSCount++;
expr = context.makePostfixNode(expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
m_assignmentCount++;
+ failIfTrueIfStrict(isEvalOrArguments);
+ failIfTrueIfStrict(requiresLExpr);
next();
break;
case MINUSMINUS:
+ m_nonTrivialExpressionCount++;
m_nonLHSCount++;
expr = context.makePostfixNode(expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
m_assignmentCount++;
+ failIfTrueIfStrict(isEvalOrArguments);
+ failIfTrueIfStrict(requiresLExpr);
next();
break;
default:
@@ -1583,7 +1904,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB
int end = lastTokenEnd();
- if (!TreeBuilder::CreatesAST)
+ if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
return expr;
while (tokenStackDepth) {
@@ -1617,6 +1938,8 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB
expr = context.createVoid(expr);
break;
case DELETETOKEN:
+ if (strictMode() && context.isResolve(expr))
+ failIfFalse(deleteProperty(m_lastIdentifier));
expr = context.makeDeleteNode(expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
break;
default:
diff --git a/JavaScriptCore/parser/JSParser.h b/JavaScriptCore/parser/JSParser.h
index ab18fab..64b18e7 100644
--- a/JavaScriptCore/parser/JSParser.h
+++ b/JavaScriptCore/parser/JSParser.h
@@ -28,9 +28,10 @@
namespace JSC {
+class ExecState;
class FunctionParameters;
class Identifier;
-class JSGlobalData;
+class JSGlobalObject;
class SourceCode;
enum {
@@ -155,6 +156,9 @@ struct JSToken {
JSTokenInfo m_info;
};
-int jsParse(JSGlobalData*, FunctionParameters*, const SourceCode*);
+enum JSParserStrictness { JSParseNormal, JSParseStrict };
+enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
+
+int jsParse(JSGlobalObject*, FunctionParameters*, JSParserStrictness, JSParserMode, const SourceCode*);
}
#endif // JSParser_h
diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index cc4321d..b443561 100644
--- a/JavaScriptCore/parser/Lexer.cpp
+++ b/JavaScriptCore/parser/Lexer.cpp
@@ -453,7 +453,7 @@ ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* lvalp, LexType lex
return IDENT;
}
-ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp)
+ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp, bool strictMode)
{
int stringQuoteCharacter = m_current;
shift();
@@ -494,6 +494,8 @@ ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp)
return false;
} else if (isASCIIOctalDigit(m_current)) {
// Octal character sequences
+ if (strictMode)
+ return false;
int character1 = m_current;
shift();
if (isASCIIOctalDigit(m_current)) {
@@ -696,7 +698,7 @@ ALWAYS_INLINE bool Lexer::parseMultilineComment()
}
}
-JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType)
+JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType, bool strictMode)
{
ASSERT(!m_error);
ASSERT(m_buffer8.isEmpty());
@@ -976,8 +978,11 @@ start:
} else {
record8('0');
if (isASCIIOctalDigit(m_current)) {
- if (parseOctal(lvalp->doubleValue))
+ if (parseOctal(lvalp->doubleValue)) {
+ if (strictMode)
+ goto returnError;
token = NUMBER;
+ }
}
}
// Fall through into CharacterNumber
@@ -1006,7 +1011,7 @@ inNumberAfterDecimalPoint:
m_delimited = false;
break;
case CharacterQuote:
- if (UNLIKELY(!parseString(lvalp)))
+ if (UNLIKELY(!parseString(lvalp, strictMode)))
goto returnError;
shift();
m_delimited = false;
@@ -1023,11 +1028,6 @@ inNumberAfterDecimalPoint:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
- if (lastTokenWasRestrKeyword()) {
- token = SEMICOLON;
- m_delimited = true;
- goto returnToken;
- }
goto start;
case CharacterInvalid:
goto returnError;
diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h
index e6c1efd..4d2513d 100644
--- a/JavaScriptCore/parser/Lexer.h
+++ b/JavaScriptCore/parser/Lexer.h
@@ -48,10 +48,11 @@ namespace JSC {
// Functions to set up parsing.
void setCode(const SourceCode&, ParserArena&);
void setIsReparsing() { m_isReparsing = true; }
+ bool isReparsing() const { return m_isReparsing; }
// Functions for the parser itself.
enum LexType { IdentifyReservedWords, IgnoreReservedWords };
- JSTokenType lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType);
+ JSTokenType lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType, bool strictMode);
int lineNumber() const { return m_lineNumber; }
void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
int lastLineNumber() const { return m_lastLineNumber; }
@@ -95,7 +96,7 @@ namespace JSC {
ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, LexType);
- ALWAYS_INLINE bool parseString(JSTokenData* lvalp);
+ ALWAYS_INLINE bool parseString(JSTokenData* lvalp, bool strictMode);
ALWAYS_INLINE void parseHex(double& returnValue);
ALWAYS_INLINE bool parseOctal(double& returnValue);
ALWAYS_INLINE bool parseDecimal(double& returnValue);
diff --git a/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp
index 534e28a..34aa674 100644
--- a/JavaScriptCore/parser/Nodes.cpp
+++ b/JavaScriptCore/parser/Nodes.cpp
@@ -89,10 +89,10 @@ ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, Var
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(JSGlobalData* globalData)
+ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext)
: StatementNode(globalData)
, ParserArenaRefCounted(globalData)
- , m_features(NoFeatures)
+ , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
{
}
@@ -154,8 +154,8 @@ FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
append(parameter->ident());
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
- : ScopeNode(globalData)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext)
+ : ScopeNode(globalData, inStrictContext)
{
}
@@ -177,9 +177,9 @@ void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters,
m_ident = ident;
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext)
{
- return new FunctionBodyNode(globalData);
+ return new FunctionBodyNode(globalData, inStrictContext);
}
PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index fa61cdc..f2a7c1e 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -57,6 +57,7 @@ namespace JSC {
const CodeFeatures WithFeature = 1 << 4;
const CodeFeatures CatchFeature = 1 << 5;
const CodeFeatures ThisFeature = 1 << 6;
+ const CodeFeatures StrictModeFeature = 1 << 7;
const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
enum Operator {
@@ -1393,7 +1394,7 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*);
+ ScopeNode(JSGlobalData*, bool inStrictContext);
ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
@@ -1410,6 +1411,7 @@ namespace JSC {
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
@@ -1444,6 +1446,7 @@ namespace JSC {
class ProgramNode : public ScopeNode {
public:
+ static const bool isFunctionNode = false;
static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
@@ -1456,6 +1459,7 @@ namespace JSC {
class EvalNode : public ScopeNode {
public:
+ static const bool isFunctionNode = false;
static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
@@ -1476,7 +1480,8 @@ namespace JSC {
class FunctionBodyNode : public ScopeNode {
public:
- static FunctionBodyNode* create(JSGlobalData*);
+ static const bool isFunctionNode = true;
+ static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode);
static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
@@ -1492,7 +1497,7 @@ namespace JSC {
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*);
+ FunctionBodyNode(JSGlobalData*, bool inStrictContext);
FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
diff --git a/JavaScriptCore/parser/Parser.cpp b/JavaScriptCore/parser/Parser.cpp
index bd77742..5092357 100644
--- a/JavaScriptCore/parser/Parser.cpp
+++ b/JavaScriptCore/parser/Parser.cpp
@@ -26,12 +26,6 @@
#include "Debugger.h"
#include "JSParser.h"
#include "Lexer.h"
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-#ifndef yyparse
-extern int jscyyparse(void*);
-#endif
#ifdef ANDROID_INSTRUMENT
#include "TimeCounter.h"
@@ -39,11 +33,15 @@ extern int jscyyparse(void*);
namespace JSC {
-void Parser::parse(JSGlobalData* globalData, FunctionParameters* parameters, int* errLine, UString* errMsg)
+void Parser::parse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg)
{
+<<<<<<< HEAD
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::JavaScriptParseTimeCounter);
#endif
+=======
+ ASSERT(lexicalGlobalObject);
+>>>>>>> webkit.org at r70209
m_sourceElements = 0;
int defaultErrLine;
@@ -57,10 +55,10 @@ void Parser::parse(JSGlobalData* globalData, FunctionParameters* parameters, int
*errLine = -1;
*errMsg = UString();
- Lexer& lexer = *globalData->lexer;
+ Lexer& lexer = *lexicalGlobalObject->globalData()->lexer;
lexer.setCode(*m_source, m_arena);
- int parseError = jsParse(globalData, parameters, m_source);
+ int parseError = jsParse(lexicalGlobalObject, parameters, strictness, mode, m_source);
int lineNumber = lexer.lineNumber();
bool lexError = lexer.sawError();
lexer.clear();
diff --git a/JavaScriptCore/parser/Parser.h b/JavaScriptCore/parser/Parser.h
index 9134de1..f5bbcb8 100644
--- a/JavaScriptCore/parser/Parser.h
+++ b/JavaScriptCore/parser/Parser.h
@@ -48,7 +48,7 @@ namespace JSC {
class Parser : public Noncopyable {
public:
template <class ParsedNode>
- PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSObject** exception);
+ PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSParserStrictness strictness, JSObject** exception);
void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features,
@@ -57,7 +57,7 @@ namespace JSC {
ParserArena& arena() { return m_arena; }
private:
- void parse(JSGlobalData*, FunctionParameters*, int* errLine, UString* errMsg);
+ void parse(JSGlobalObject* lexicalGlobalObject, FunctionParameters*, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg);
// Used to determine type of error to report.
bool isFunctionBodyNode(ScopeNode*) { return false; }
@@ -75,20 +75,21 @@ namespace JSC {
};
template <class ParsedNode>
- PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSObject** exception)
+ PassRefPtr<ParsedNode> Parser::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSObject** exception)
{
+ ASSERT(lexicalGlobalObject);
ASSERT(exception && !*exception);
int errLine;
UString errMsg;
m_source = &source;
if (ParsedNode::scopeIsFunction)
- globalData->lexer->setIsReparsing();
- parse(globalData, parameters, &errLine, &errMsg);
+ lexicalGlobalObject->globalData()->lexer->setIsReparsing();
+ parse(lexicalGlobalObject, parameters, strictness, ParsedNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, &errLine, &errMsg);
RefPtr<ParsedNode> result;
if (m_sourceElements) {
- result = ParsedNode::create(globalData,
+ result = ParsedNode::create(lexicalGlobalObject->globalData(),
m_sourceElements,
m_varDeclarations ? &m_varDeclarations->data : 0,
m_funcDeclarations ? &m_funcDeclarations->data : 0,
@@ -107,7 +108,7 @@ namespace JSC {
if (isFunctionBodyNode(static_cast<ParsedNode*>(0)))
*exception = createStackOverflowError(lexicalGlobalObject);
else
- *exception = addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, source);
+ *exception = addErrorInfo(lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, source);
}
m_arena.reset();
diff --git a/JavaScriptCore/parser/SyntaxChecker.h b/JavaScriptCore/parser/SyntaxChecker.h
index ce3ab61..f9093a7 100644
--- a/JavaScriptCore/parser/SyntaxChecker.h
+++ b/JavaScriptCore/parser/SyntaxChecker.h
@@ -30,15 +30,24 @@ namespace JSC {
class SyntaxChecker {
public:
SyntaxChecker(JSGlobalData* , Lexer*)
+ : m_topBinaryExpr(0)
{
}
typedef SyntaxChecker FunctionBodyBuilder;
+ enum { NoneExpr = 0,
+ ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr,
+ ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
+ FunctionExpr, BracketExpr, DotExpr, CallExpr,
+ NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
+ ConditionalExpr, AssignmentExpr, TypeofExpr,
+ DeleteExpr, ArrayLiteralExpr };
+ typedef int ExpressionType;
- typedef int Expression;
+ typedef ExpressionType Expression;
typedef int SourceElements;
typedef int Arguments;
- typedef int Comma;
+ typedef ExpressionType Comma;
struct Property {
ALWAYS_INLINE Property(void* = 0)
: type((PropertyNode::Type)0)
@@ -73,38 +82,38 @@ public:
static const bool NeedsFreeVariableInfo = false;
int createSourceElements() { return 1; }
- int makeFunctionCallNode(int, int, int, int, int) { return 1; }
- void appendToComma(int, int) { }
- int createCommaExpr(int, int) { return 1; }
- int makeAssignNode(int, Operator, int, bool, bool, int, int, int) { return 1; }
- int makePrefixNode(int, Operator, int, int, int) { return 1; }
- int makePostfixNode(int, Operator, int, int, int) { return 1; }
- int makeTypeOfNode(int) { return 1; }
- int makeDeleteNode(int, int, int, int) { return 1; }
- int makeNegateNode(int) { return 1; }
- int makeBitwiseNotNode(int) { return 1; }
- int createLogicalNot(int) { return 1; }
- int createUnaryPlus(int) { return 1; }
- int createVoid(int) { return 1; }
- int thisExpr() { return 1; }
- int createResolve(const Identifier*, int) { return 1; }
- int createObjectLiteral() { return 1; }
- int createObjectLiteral(int) { return 1; }
- int createArray(int) { return 1; }
- int createArray(int, int) { return 1; }
- int createNumberExpr(double) { return 1; }
- int createString(const Identifier*) { return 1; }
- int createBoolean(bool) { return 1; }
- int createNull() { return 1; }
- int createBracketAccess(int, int, bool, int, int, int) { return 1; }
- int createDotAccess(int, const Identifier&, int, int, int) { return 1; }
- int createRegex(const Identifier&, const Identifier&, int) { return 1; }
- int createNewExpr(int, int, int, int, int) { return 1; }
- int createNewExpr(int, int, int) { return 1; }
- int createConditionalExpr(int, int, int) { return 1; }
- int createAssignResolve(const Identifier&, int, bool, int, int, int) { return 1; }
- int createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return 1; }
- int createFunctionBody() { return 1; }
+ ExpressionType makeFunctionCallNode(int, int, int, int, int) { return CallExpr; }
+ void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
+ ExpressionType createCommaExpr(ExpressionType, ExpressionType right) { return right; }
+ ExpressionType makeAssignNode(ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
+ ExpressionType makePrefixNode(ExpressionType, Operator, int, int, int) { return PreExpr; }
+ ExpressionType makePostfixNode(ExpressionType, Operator, int, int, int) { return PostExpr; }
+ ExpressionType makeTypeOfNode(ExpressionType) { return TypeofExpr; }
+ ExpressionType makeDeleteNode(ExpressionType, int, int, int) { return DeleteExpr; }
+ ExpressionType makeNegateNode(ExpressionType) { return UnaryExpr; }
+ ExpressionType makeBitwiseNotNode(ExpressionType) { return UnaryExpr; }
+ ExpressionType createLogicalNot(ExpressionType) { return UnaryExpr; }
+ ExpressionType createUnaryPlus(ExpressionType) { return UnaryExpr; }
+ ExpressionType createVoid(ExpressionType) { return UnaryExpr; }
+ ExpressionType thisExpr() { return ThisExpr; }
+ ExpressionType createResolve(const Identifier*, int) { return ResolveExpr; }
+ ExpressionType createObjectLiteral() { return ObjectLiteralExpr; }
+ ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; }
+ ExpressionType createArray(int) { return ArrayLiteralExpr; }
+ ExpressionType createArray(int, int) { return ArrayLiteralExpr; }
+ ExpressionType createNumberExpr(double) { return NumberExpr; }
+ ExpressionType createString(const Identifier*) { return StringExpr; }
+ ExpressionType createBoolean(bool) { return BoolExpr; }
+ ExpressionType createNull() { return NullExpr; }
+ ExpressionType createBracketAccess(ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
+ ExpressionType createDotAccess(ExpressionType, const Identifier&, int, int, int) { return DotExpr; }
+ ExpressionType createRegex(const Identifier&, const Identifier&, int) { return RegExpExpr; }
+ ExpressionType createNewExpr(ExpressionType, int, int, int, int) { return NewExpr; }
+ ExpressionType createNewExpr(ExpressionType, int, int) { return NewExpr; }
+ ExpressionType createConditionalExpr(ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
+ ExpressionType createAssignResolve(const Identifier&, ExpressionType, bool, int, int, int) { return AssignmentExpr; }
+ ExpressionType createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
+ int createFunctionBody(bool) { return 1; }
int createArguments() { return 1; }
int createArguments(int) { return 1; }
int createArgumentsList(int) { return 1; }
@@ -169,26 +178,38 @@ public:
void addVar(const Identifier*, bool) { }
int combineCommaNodes(int, int) { return 1; }
int evalCount() const { return 0; }
- void appendBinaryExpressionInfo(int& operandStackDepth, int, int, int, int, bool) { operandStackDepth++; }
+ void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
+ {
+ if (!m_topBinaryExpr)
+ m_topBinaryExpr = expr;
+ else
+ m_topBinaryExpr = BinaryExpr;
+ operandStackDepth++;
+ }
// Logic to handle datastructures used during parsing of binary expressions
void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; }
bool operatorStackHasHigherPrecedence(int&, int) { return true; }
- BinaryOperand getFromOperandStack(int) { return 1; }
+ BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; }
void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; }
void appendBinaryOperation(int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
- int popOperandStack(int&) { return 1; }
+ int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
- void appendUnaryToken(int&, int, int) { }
- int unaryTokenStackLastType(int&) { ASSERT_NOT_REACHED(); return 1; }
- int unaryTokenStackLastStart(int&) { ASSERT_NOT_REACHED(); return 1; }
- void unaryTokenStackRemoveLast(int&) { }
+ void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; }
+ int unaryTokenStackLastType(int&) { return m_topUnaryToken; }
+ int unaryTokenStackLastStart(int&) { return 0; }
+ void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
void assignmentStackAppend(int, int, int, int, int, Operator) { }
int createAssignment(int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; }
const Identifier& getName(const Property& property) { ASSERT(property.name); return *property.name; }
PropertyNode::Type getType(const Property& property) { return property.type; }
+ bool isResolve(ExpressionType expr) { return expr == ResolveExpr || expr == ResolveEvalExpr; }
+
+private:
+ int m_topBinaryExpr;
+ int m_topUnaryToken;
};
}
diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp
index 021ecff..78fe2f5 100644
--- a/JavaScriptCore/profiler/Profiler.cpp
+++ b/JavaScriptCore/profiler/Profiler.cpp
@@ -39,7 +39,7 @@
#include "Profile.h"
#include "ProfileGenerator.h"
#include "ProfileNode.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <stdio.h>
namespace JSC {
@@ -152,7 +152,7 @@ CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionV
return CallIdentifier(static_cast<JSFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
if (asObject(functionValue)->inherits(&InternalFunction::info))
return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
- return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
+ return CallIdentifier(makeUString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
}
CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function)
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index 450dc7d..5c5e522 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -153,6 +153,30 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl
return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot);
}
+
+void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
+{
+ if (d->overrodeCaller)
+ return;
+
+ d->overrodeCaller = true;
+ PropertyDescriptor descriptor;
+ JSValue thrower = createTypeErrorFunction(exec, "Unable to access caller of strict mode function");
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+ defineOwnProperty(exec, exec->propertyNames().caller, descriptor, false);
+}
+
+void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
+{
+ if (d->overrodeCallee)
+ return;
+
+ d->overrodeCallee = true;
+ PropertyDescriptor descriptor;
+ JSValue thrower = createTypeErrorFunction(exec, "Unable to access callee of strict mode function");
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+ defineOwnProperty(exec, exec->propertyNames().callee, descriptor, false);
+}
bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
@@ -172,10 +196,16 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
}
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
- slot.setValue(d->callee);
- return true;
+ if (!d->isStrictMode) {
+ slot.setValue(d->callee);
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
+
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
@@ -197,9 +227,15 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop
}
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
- descriptor.setDescriptor(d->callee, DontEnum);
- return true;
+ if (!d->isStrictMode) {
+ descriptor.setDescriptor(d->callee, DontEnum);
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
@@ -249,11 +285,17 @@ void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue val
}
if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
- d->overrodeCallee = true;
- putDirect(propertyName, value, DontEnum);
- return;
+ if (!d->isStrictMode) {
+ d->overrodeCallee = true;
+ putDirect(propertyName, value, DontEnum);
+ return;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
+
JSObject::put(exec, propertyName, value, slot);
}
@@ -294,9 +336,15 @@ bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
}
if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
- d->overrodeCallee = true;
- return true;
+ if (!d->isStrictMode) {
+ d->overrodeCallee = true;
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+
+ if (propertyName == exec->propertyNames().caller && !d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
return JSObject::deleteProperty(exec, propertyName);
}
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
index 49c8b3b..715a2ac 100644
--- a/JavaScriptCore/runtime/Arguments.h
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -50,6 +50,8 @@ namespace JSC {
JSFunction* callee;
bool overrodeLength : 1;
bool overrodeCallee : 1;
+ bool overrodeCaller : 1;
+ bool isStrictMode : 1;
};
@@ -105,6 +107,8 @@ namespace JSC {
virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
+ void createStrictModeCallerIfNecessary(ExecState*);
+ void createStrictModeCalleeIfNecessary(ExecState*);
virtual const ClassInfo* classInfo() const { return &info; }
@@ -172,6 +176,10 @@ namespace JSC {
d->callee = callee;
d->overrodeLength = false;
d->overrodeCallee = false;
+ d->overrodeCaller = false;
+ d->isStrictMode = callFrame->codeBlock()->isStrictMode();
+ if (d->isStrictMode)
+ copyRegisters();
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
@@ -201,6 +209,10 @@ namespace JSC {
d->callee = asFunction(callFrame->callee());
d->overrodeLength = false;
d->overrodeCallee = false;
+ d->overrodeCaller = false;
+ d->isStrictMode = callFrame->codeBlock()->isStrictMode();
+ if (d->isStrictMode)
+ copyRegisters();
}
inline void Arguments::copyRegisters()
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 28269ff..6002ebb 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -180,7 +180,14 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
+#if OS(SYMBIAN)
+ // Symbian has very limited stack size available.
+ // This function could be called recursively and allocating 1K on stack here cause
+ // stack overflow on Symbian devices.
+ Vector<RefPtr<StringImpl> > strBuffer(length);
+#else
Vector<RefPtr<StringImpl>, 256> strBuffer(length);
+#endif
for (unsigned k = 0; k < length; k++) {
JSValue element;
if (isRealArray && thisObj->canGetIndex(k))
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 93b91bb..f341646 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -642,19 +642,6 @@ inline bool isPointerAligned(void* p)
// Cell size needs to be a power of two for isPossibleCell to be valid.
COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two);
-#if USE(JSVALUE32)
-static bool isHalfCellAligned(void *p)
-{
- return (((intptr_t)(p) & (CELL_MASK >> 1)) == 0);
-}
-
-static inline bool isPossibleCell(void* p)
-{
- return isHalfCellAligned(p) && p;
-}
-
-#else
-
static inline bool isCellAligned(void *p)
{
return (((intptr_t)(p) & CELL_MASK) == 0);
@@ -664,7 +651,6 @@ static inline bool isPossibleCell(void* p)
{
return isCellAligned(p) && p;
}
-#endif // USE(JSVALUE32)
void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
{
@@ -1145,10 +1131,6 @@ static const char* typeName(JSCell* cell)
{
if (cell->isString())
return "string";
-#if USE(JSVALUE32)
- if (cell->isNumber())
- return "number";
-#endif
if (cell->isGetterSetter())
return "Getter-Setter";
if (cell->isAPIValueWrapper())
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 05d5c10..237c139 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -57,7 +57,7 @@ namespace JSC {
class LiveObjectIterator;
-#if OS(WINCE) || OS(SYMBIAN)
+#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
const size_t BLOCK_SIZE = 64 * 1024; // 64k
#else
const size_t BLOCK_SIZE = 256 * 1024; // 256k
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp
index 3837817..1561102 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -32,6 +32,7 @@ CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
, emptyIdentifier(globalData, "")
, underscoreProto(globalData, "__proto__")
, thisIdentifier(globalData, "this")
+ , useStrictIdentifier(globalData, "use strict")
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
{
}
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index de24f4a..1e22b6a 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -94,6 +94,7 @@ namespace JSC {
const Identifier emptyIdentifier;
const Identifier underscoreProto;
const Identifier thisIdentifier;
+ const Identifier useStrictIdentifier;
#define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp
index 7eb82e4..d4b8232 100644
--- a/JavaScriptCore/runtime/DateConversion.cpp
+++ b/JavaScriptCore/runtime/DateConversion.cpp
@@ -57,7 +57,9 @@ double parseDate(ExecState* exec, const UString &date)
{
if (date == exec->globalData().cachedDateString)
return exec->globalData().cachedDateStringValue;
- double value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
+ double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
+ if (isnan(value))
+ value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
exec->globalData().cachedDateString = date;
exec->globalData().cachedDateStringValue = value;
return value;
diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp
index a2be473..e35424b 100644
--- a/JavaScriptCore/runtime/Error.cpp
+++ b/JavaScriptCore/runtime/Error.cpp
@@ -195,4 +195,47 @@ JSObject* throwSyntaxError(ExecState* exec)
return throwError(exec, createSyntaxError(exec, "Syntax error"));
}
+class StrictModeTypeErrorFunction : public InternalFunction {
+public:
+ StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& message)
+ : InternalFunction(&exec->globalData(), globalObject, structure, exec->globalData().propertyNames->emptyIdentifier)
+ , m_message(message)
+ {
+ }
+
+ static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
+ {
+ throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+ return JSValue::encode(jsNull());
+ }
+
+ ConstructType getConstructData(ConstructData& constructData)
+ {
+ constructData.native.function = constructThrowTypeError;
+ return ConstructTypeHost;
+ }
+
+ static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
+ {
+ throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+ return JSValue::encode(jsNull());
+ }
+
+ CallType getCallData(CallData& callData)
+ {
+ callData.native.function = callThrowTypeError;
+ return CallTypeHost;
+ }
+
+private:
+ UString m_message;
+};
+
+COMPILE_ASSERT(sizeof(StrictModeTypeErrorFunction) <= sizeof(CollectorCell), sizeof_StrictModeTypeErrorFunction_must_be_less_than_CollectorCell);
+
+JSValue createTypeErrorFunction(ExecState* exec, const UString& message)
+{
+ return new (exec) StrictModeTypeErrorFunction(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->internalFunctionStructure(), message);
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Error.h b/JavaScriptCore/runtime/Error.h
index 1a0ece5..bfde7dc 100644
--- a/JavaScriptCore/runtime/Error.h
+++ b/JavaScriptCore/runtime/Error.h
@@ -73,6 +73,8 @@ namespace JSC {
inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); }
inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
+ JSValue createTypeErrorFunction(ExecState* exec, const UString& message);
+
} // namespace JSC
#endif // Error_h
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 9a6fe5e..a1e28d1 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -36,7 +36,7 @@
#include "JSNotAnObject.h"
#include "Interpreter.h"
#include "Nodes.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -90,7 +90,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
- UString message(makeString("Can't find variable: ", ident.ustring()));
+ UString message(makeUString("Can't find variable: ", ident.ustring()));
JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
return exception;
}
@@ -98,9 +98,9 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
{
if (!expressionStop || expressionStart > codeBlock->source()->length())
- return makeString(value.toString(exec), " is ", error);
+ return makeUString(value.toString(exec), " is ", error);
if (expressionStart < expressionStop)
- return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
+ return makeUString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
// No range information, so give a few characters of context
const UChar* data = codeBlock->source()->data();
@@ -117,7 +117,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
stop++;
while (stop > expressionStart && isStrWhiteSpace(data[stop]))
stop--;
- return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
+ return makeUString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
}
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
@@ -126,7 +126,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
- UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeUString("not a valid argument for '", op, "'"));
JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
return exception;
}
@@ -192,4 +192,9 @@ JSValue throwOutOfMemoryError(ExecState* exec)
return throwError(exec, createError(exec, "Out of memory"));
}
+JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const UString& propertyName)
+{
+ return createReferenceError(exec, makeUString("Strict mode forbids implicit creation of global property '", propertyName, "'"));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index 3e6de86..9b6f1f2 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -54,6 +54,7 @@ namespace JSC {
JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
JSValue throwOutOfMemoryError(ExecState*);
+ JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const UString&);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 871f3e2..2ad4b2d 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -30,7 +30,7 @@
#include "CodeBlock.h"
#include "JIT.h"
#include "Parser.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include "Vector.h"
namespace JSC {
@@ -45,8 +45,8 @@ VPtrHackExecutable::~VPtrHackExecutable()
{
}
-EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
+EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
+ : ScriptExecutable(exec, source, inStrictContext)
{
}
@@ -55,7 +55,7 @@ EvalExecutable::~EvalExecutable()
}
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
+ : ScriptExecutable(exec, source, false)
{
}
@@ -63,8 +63,8 @@ ProgramExecutable::~ProgramExecutable()
{
}
-FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(globalData, source)
+FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
+ : ScriptExecutable(globalData, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -75,8 +75,8 @@ FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifie
m_lastLine = lastLine;
}
-FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(exec, source)
+FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
+ : ScriptExecutable(exec, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -96,7 +96,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!evalNode) {
ASSERT(exception);
return exception;
@@ -131,7 +131,7 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, JSParseNormal, &exception);
if (programNode)
return 0;
ASSERT(exception);
@@ -145,7 +145,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!programNode) {
ASSERT(exception);
return exception;
@@ -178,7 +178,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -219,7 +219,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -264,12 +264,14 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
m_codeBlockForConstruct->markAggregate(markStack);
}
-PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, m_parameters.get(), &exception);
+ JSGlobalData* globalData = scopeChainNode->globalData;
+ RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(scopeChainNode->globalObject, 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!newFunctionBody)
return PassOwnPtr<ExceptionInfo>();
+ ASSERT(newFunctionBody->isStrictMode() == isStrictMode());
if (m_forceUsesArguments)
newFunctionBody->setUsesArguments();
newFunctionBody->finishParsing(m_parameters, m_name);
@@ -298,10 +300,12 @@ PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData*
return newCodeBlock->extractExceptionInfo();
}
-PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, 0, &exception);
+ JSGlobalData* globalData = scopeChainNode->globalData;
+ RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(scopeChainNode->globalObject, 0, 0, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
+ ASSERT(newEvalBody->isStrictMode() == isStrictMode());
if (!newEvalBody)
return PassOwnPtr<ExceptionInfo>();
@@ -341,7 +345,7 @@ void FunctionExecutable::recompile(ExecState*)
PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, debugger, exec, source, 0, exception);
+ RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception);
if (!program) {
ASSERT(*exception);
return 0;
@@ -357,22 +361,22 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi
FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
- return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
+ return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
UString FunctionExecutable::paramString() const
{
FunctionParameters& parameters = *m_parameters;
- StringBuilder builder;
+ UStringBuilder builder;
for (size_t pos = 0; pos < parameters.size(); ++pos) {
if (!builder.isEmpty())
builder.append(", ");
builder.append(parameters[pos].ustring());
}
- return builder.build();
+ return builder.toUString();
}
-PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*)
+PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(ScopeChainNode*, CodeBlock*)
{
// CodeBlocks for program code are transient and therefore do not gain from from throwing out their exception information.
return PassOwnPtr<ExceptionInfo>();
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index feab7ef..4c4ca56 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -138,10 +138,10 @@ namespace JSC {
class ScriptExecutable : public ExecutableBase {
public:
- ScriptExecutable(JSGlobalData* globalData, const SourceCode& source)
+ ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(0)
+ , m_features(isInStrictContext ? StrictModeFeature : 0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
relaxAdoptionRequirement();
@@ -152,10 +152,10 @@ namespace JSC {
#endif
}
- ScriptExecutable(ExecState* exec, const SourceCode& source)
+ ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(0)
+ , m_features(isInStrictContext ? StrictModeFeature : 0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
relaxAdoptionRequirement();
@@ -175,8 +175,9 @@ namespace JSC {
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*) = 0;
protected:
void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
@@ -214,7 +215,7 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
+ static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); }
#if ENABLE(JIT)
JITCode& generatedJITCode()
@@ -224,11 +225,11 @@ namespace JSC {
#endif
private:
- EvalExecutable(ExecState*, const SourceCode&);
+ EvalExecutable(ExecState*, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
@@ -271,7 +272,7 @@ namespace JSC {
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
@@ -279,14 +280,14 @@ namespace JSC {
class FunctionExecutable : public ScriptExecutable {
friend class JIT;
public:
- static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));
+ return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
}
- static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));
+ return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
}
~FunctionExecutable();
@@ -358,13 +359,13 @@ namespace JSC {
static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
private:
- FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
- FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
+ FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
+ FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index f72a273..9b59720 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -30,8 +30,8 @@
#include "Lexer.h"
#include "Nodes.h"
#include "Parser.h"
-#include "StringBuilder.h"
-#include "StringConcatenate.h"
+#include "UStringBuilder.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -81,9 +81,9 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
if (args.isEmpty())
program = "(function() { \n})";
else if (args.size() == 1)
- program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
+ program = makeUString("(function() { ", args.at(0).toString(exec), "\n})");
else {
- StringBuilder builder;
+ UStringBuilder builder;
builder.append("(function(");
builder.append(args.at(0).toString(exec));
for (size_t i = 1; i < args.size() - 1; i++) {
@@ -93,7 +93,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
builder.append(") { ");
builder.append(args.at(args.size() - 1).toString(exec));
builder.append("\n})");
- program = builder.build();
+ program = builder.toUString();
}
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index c740624..ef42cdc 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -77,7 +77,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
UChar ch = functionBody[i];
if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
if (ch != ';' && ch != '}')
- functionBody = makeString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1)));
+ functionBody = makeUString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1)));
return;
}
}
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index d121518..795ad1f 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -186,6 +186,11 @@ JSObject* JSActivation::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
+JSValue JSActivation::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
requiresDynamicChecks = d()->functionExecutable->usesEval();
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 9ff9168..6dd6d70 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -60,6 +60,7 @@ namespace JSC {
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
void copyRegisters();
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index cfa1454..1a7f8b2 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -75,9 +75,6 @@ namespace JSC {
}
// Querying the type.
-#if USE(JSVALUE32)
- bool isNumber() const;
-#endif
bool isString() const;
bool isObject() const;
virtual bool isGetterSetter() const;
@@ -156,13 +153,6 @@ namespace JSC {
{
}
-#if USE(JSVALUE32)
- inline bool JSCell::isNumber() const
- {
- return m_structure->typeInfo().type() == NumberType;
- }
-#endif
-
inline bool JSCell::isObject() const
{
return m_structure->typeInfo().type() == ObjectType;
@@ -253,13 +243,13 @@ namespace JSC {
return false;
}
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
ALWAYS_INLINE JSCell* JSValue::asCell() const
{
ASSERT(isCell());
return m_ptr;
}
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index 7eb9ba5..fdaa509 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -122,6 +122,15 @@ JSFunction::~JSFunction()
}
}
+static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
+static const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function";
+
+static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
+{
+ JSValue thrower = createTypeErrorFunction(exec, message);
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+}
+
const UString& JSFunction::name(ExecState* exec)
{
return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue();
@@ -209,6 +218,12 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
}
if (propertyName == exec->propertyNames().arguments) {
+ if (jsExecutable()->isStrictMode()) {
+ throwTypeError(exec, "Can't access arguments object of a strict mode function");
+ slot.setValue(jsNull());
+ return true;
+ }
+
slot.setCacheableCustom(this, argumentsGetter);
return true;
}
@@ -219,6 +234,11 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
}
if (propertyName == exec->propertyNames().caller) {
+ if (jsExecutable()->isStrictMode()) {
+ throwTypeError(exec, StrictModeCallerAccessError);
+ slot.setValue(jsNull());
+ return true;
+ }
slot.setCacheableCustom(this, callerGetter);
return true;
}
@@ -226,35 +246,41 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
}
- bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
- {
- if (isHostFunction())
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
-
- if (propertyName == exec->propertyNames().prototype) {
- PropertySlot slot;
- getOwnPropertySlot(exec, propertyName, slot);
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
- }
-
- if (propertyName == exec->propertyNames().arguments) {
+bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+{
+ if (isHostFunction())
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ PropertySlot slot;
+ getOwnPropertySlot(exec, propertyName, slot);
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ }
+
+ if (propertyName == exec->propertyNames().arguments) {
+ if (jsExecutable()->isStrictMode())
+ createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError);
+ else
descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- if (propertyName == exec->propertyNames().length) {
- descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- if (propertyName == exec->propertyNames().caller) {
+ return true;
+ }
+
+ if (propertyName == exec->propertyNames().length) {
+ descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
+ return true;
+ }
+
+ if (propertyName == exec->propertyNames().caller) {
+ if (jsExecutable()->isStrictMode())
+ createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError);
+ else
descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ return true;
}
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+}
+
void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
@@ -272,6 +298,16 @@ void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue va
Base::put(exec, propertyName, value, slot);
return;
}
+ if (jsExecutable()->isStrictMode()) {
+ if (propertyName == exec->propertyNames().arguments) {
+ throwTypeError(exec, StrictModeArgumentsAccessError);
+ return;
+ }
+ if (propertyName == exec->propertyNames().caller) {
+ throwTypeError(exec, StrictModeCallerAccessError);
+ return;
+ }
+ }
if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
return;
Base::put(exec, propertyName, value, slot);
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 5eaa59b..1404ddf 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -50,6 +50,7 @@
#include "Nodes.h"
#include "Parser.h"
#include "RegExpCache.h"
+#include "StrictEvalActivation.h"
#include <wtf/WTFThreadData.h>
#if ENABLE(REGEXP_TRACING)
#include "RegExp.h"
@@ -124,6 +125,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
, terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
, staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
+ , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull()))
, stringStructure(JSString::createStructure(jsNull()))
, notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
, notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
@@ -131,9 +133,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, getterSetterStructure(GetterSetter::createStructure(jsNull()))
, apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
, dummyMarkableCellStructure(JSCell::createDummyStructure())
-#if USE(JSVALUE32)
- , numberStructure(JSNumberCell::createStructure(jsNull()))
-#endif
, identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 8e2ed61..775d026 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -145,6 +145,7 @@ namespace JSC {
RefPtr<Structure> interruptedExecutionErrorStructure;
RefPtr<Structure> terminatedExecutionErrorStructure;
RefPtr<Structure> staticScopeStructure;
+ RefPtr<Structure> strictEvalActivationStructure;
RefPtr<Structure> stringStructure;
RefPtr<Structure> notAnObjectErrorStubStructure;
RefPtr<Structure> notAnObjectStructure;
@@ -153,10 +154,6 @@ namespace JSC {
RefPtr<Structure> apiWrapperStructure;
RefPtr<Structure> dummyMarkableCellStructure;
-#if USE(JSVALUE32)
- RefPtr<Structure> numberStructure;
-#endif
-
static void storeVPtrs();
static JS_EXPORTDATA void* jsArrayVPtr;
static JS_EXPORTDATA void* jsByteArrayVPtr;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index 89c042a..903e573 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -204,6 +204,7 @@ void JSGlobalObject::reset(JSValue prototype)
d()->functionPrototype = new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
+ d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype);
NativeFunctionWrapper* callFunction = 0;
NativeFunctionWrapper* applyFunction = 0;
d()->functionPrototype->addFunctionProperties(exec, this, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index f5d2fb0..36fa70b 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -148,6 +148,7 @@ namespace JSC {
RefPtr<Structure> regExpMatchesArrayStructure;
RefPtr<Structure> regExpStructure;
RefPtr<Structure> stringObjectStructure;
+ RefPtr<Structure> internalFunctionStructure;
SymbolTable symbolTable;
unsigned profileGroup;
@@ -243,6 +244,7 @@ namespace JSC {
Structure* functionStructure() const { return d()->functionStructure.get(); }
Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
+ Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); }
Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
Structure* regExpStructure() const { return d()->regExpStructure.get(); }
Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
@@ -384,16 +386,8 @@ namespace JSC {
if (typeInfo().type() == ObjectType)
return m_prototype;
-#if USE(JSVALUE32)
- if (typeInfo().type() == StringType)
- return exec->lexicalGlobalObject()->stringPrototype();
-
- ASSERT(typeInfo().type() == NumberType);
- return exec->lexicalGlobalObject()->numberPrototype();
-#else
ASSERT(typeInfo().type() == StringType);
return exec->lexicalGlobalObject()->stringPrototype();
-#endif
}
inline StructureChain* Structure::prototypeChain(ExecState* exec) const
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 1e20f7f..ed06fa5 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -35,7 +35,7 @@
#include "LiteralParser.h"
#include "Nodes.h"
#include "Parser.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include "dtoa.h"
#include <stdio.h>
#include <stdlib.h>
@@ -450,7 +450,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
if (JSValue parsedObject = preparser.tryLiteralParse())
return JSValue::encode(parsedObject);
- RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s));
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false);
JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node());
if (error)
return throwVMError(exec, error);
@@ -563,7 +563,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
{
- StringBuilder builder;
+ UStringBuilder builder;
UString str = exec->argument(0).toString(exec);
int k = 0;
int len = str.length();
@@ -585,7 +585,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
builder.append(*c);
}
- return JSValue::encode(jsString(exec, builder.build()));
+ return JSValue::encode(jsString(exec, builder.toUString()));
}
#ifndef NDEBUG
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
index 9127b6a..ffa446e 100644
--- a/JavaScriptCore/runtime/JSImmediate.h
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -22,7 +22,7 @@
#ifndef JSImmediate_h
#define JSImmediate_h
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include <wtf/Assertions.h>
#include <wtf/AlwaysInline.h>
@@ -44,7 +44,6 @@ namespace JSC {
class JSObject;
class UString;
-#if USE(JSVALUE64)
inline intptr_t reinterpretDoubleToIntptr(double value)
{
return WTF::bitwise_cast<intptr_t>(value);
@@ -54,7 +53,6 @@ namespace JSC {
{
return WTF::bitwise_cast<double>(value);
}
-#endif
/*
* A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged
@@ -159,16 +157,12 @@ namespace JSC {
friend JSValue jsNumber(JSGlobalData* globalData, long long i);
friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
-#if USE(JSVALUE64)
// If all bits in the mask are set, this indicates an integer number,
// if any but not all are set this value is a double precision number.
static const intptr_t TagTypeNumber = 0xffff000000000000ll;
// This value is 2^48, used to encode doubles such that the encoded value will begin
// with a 16-bit pattern within the range 0x0001..0xFFFE.
static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
-#elif USE(JSVALUE32)
- static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
-#endif
static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
@@ -181,11 +175,7 @@ namespace JSC {
static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
static const intptr_t FullTagTypeNull = TagBitTypeOther;
-#if USE(JSVALUE64)
static const int32_t IntegerPayloadShift = 0;
-#else
- static const int32_t IntegerPayloadShift = 1;
-#endif
static const int32_t ExtendedPayloadShift = 4;
static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
@@ -204,19 +194,13 @@ namespace JSC {
static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
{
-#if USE(JSVALUE64)
return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
-#else
- return isNumber(v);
-#endif
}
-#if USE(JSVALUE64)
static ALWAYS_INLINE bool isDouble(JSValue v)
{
return isNumber(v) && !isIntegerNumber(v);
}
-#endif
static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
{
@@ -260,11 +244,7 @@ namespace JSC {
static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
{
-#if USE(JSVALUE64)
return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
-#else
- return rawValue(v1) & rawValue(v2) & TagTypeNumber;
-#endif
}
static double toDouble(JSValue);
@@ -285,13 +265,8 @@ namespace JSC {
static JSValue oneImmediate();
private:
-#if USE(JSVALUE64)
static const int minImmediateInt = ((-INT_MAX) - 1);
static const int maxImmediateInt = INT_MAX;
-#else
- static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
- static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
-#endif
static const unsigned maxImmediateUInt = maxImmediateInt;
static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
@@ -302,21 +277,15 @@ namespace JSC {
// With USE(JSVALUE64) we want the argument to be zero extended, so the
// integer doesn't interfere with the tag bits in the upper word. In the default encoding,
// if intptr_t id larger then int32_t we sign extend the value through the upper word.
-#if USE(JSVALUE64)
static ALWAYS_INLINE JSValue makeInt(uint32_t value)
-#else
- static ALWAYS_INLINE JSValue makeInt(int32_t value)
-#endif
{
return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
}
-#if USE(JSVALUE64)
static ALWAYS_INLINE JSValue makeDouble(double value)
{
return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
}
-#endif
static ALWAYS_INLINE JSValue makeBool(bool b)
{
@@ -336,12 +305,10 @@ namespace JSC {
template<typename T>
static JSValue fromNumberOutsideIntegerRange(T);
-#if USE(JSVALUE64)
static ALWAYS_INLINE double doubleValue(JSValue v)
{
return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
}
-#endif
static ALWAYS_INLINE int32_t intValue(JSValue v)
{
@@ -371,7 +338,6 @@ namespace JSC {
ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); }
ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
-#if USE(JSVALUE64)
inline bool doubleToBoolean(double value)
{
return value < 0.0 || value > 0.0;
@@ -383,13 +349,6 @@ namespace JSC {
return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
: doubleToBoolean(doubleValue(v)) : v == trueImmediate();
}
-#else
- ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
- {
- ASSERT(isImmediate(v));
- return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
- }
-#endif
ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
{
@@ -398,19 +357,11 @@ namespace JSC {
return intValue(v);
}
-#if USE(JSVALUE64)
template<typename T>
inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
{
return makeDouble(static_cast<double>(value));
}
-#else
- template<typename T>
- inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T)
- {
- return JSValue();
- }
-#endif
ALWAYS_INLINE JSValue JSImmediate::from(char i)
{
@@ -439,10 +390,6 @@ namespace JSC {
ALWAYS_INLINE JSValue JSImmediate::from(int i)
{
-#if !USE(JSVALUE64)
- if ((i < minImmediateInt) | (i > maxImmediateInt))
- return fromNumberOutsideIntegerRange(i);
-#endif
return makeInt(i);
}
@@ -505,14 +452,10 @@ namespace JSC {
if (isIntegerNumber(v))
return intValue(v);
-#if USE(JSVALUE64)
if (isNumber(v)) {
ASSERT(isDouble(v));
return doubleValue(v);
}
-#else
- ASSERT(!isNumber(v));
-#endif
if (rawValue(v) == FullTagTypeUndefined)
return nonInlineNaN();
@@ -670,11 +613,7 @@ namespace JSC {
static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift)
{
ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
-#if USE(JSVALUE64)
return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
-#else
- return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);
-#endif
}
static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v)
@@ -718,6 +657,6 @@ namespace JSC {
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // JSImmediate_h
diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp
index 77388e0..6fa6b2a 100644
--- a/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -23,75 +23,6 @@
#include "config.h"
#include "JSNumberCell.h"
-#if USE(JSVALUE32)
-
-#include "NumberObject.h"
-#include "UString.h"
-
-namespace JSC {
-
-JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
-{
- return const_cast<JSNumberCell*>(this);
-}
-
-bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
-{
- number = m_value;
- value = this;
- return true;
-}
-
-bool JSNumberCell::toBoolean(ExecState*) const
-{
- return m_value < 0.0 || m_value > 0.0; // false for NaN
-}
-
-double JSNumberCell::toNumber(ExecState*) const
-{
- return m_value;
-}
-
-UString JSNumberCell::toString(ExecState*) const
-{
- return UString::number(m_value);
-}
-
-JSObject* JSNumberCell::toObject(ExecState* exec) const
-{
- return constructNumber(exec, const_cast<JSNumberCell*>(this));
-}
-
-JSObject* JSNumberCell::toThisObject(ExecState* exec) const
-{
- return constructNumber(exec, const_cast<JSNumberCell*>(this));
-}
-
-bool JSNumberCell::getUInt32(uint32_t& uint32) const
-{
- uint32 = static_cast<uint32_t>(m_value);
- return uint32 == m_value;
-}
-
-JSValue JSNumberCell::getJSNumber()
-{
- return this;
-}
-
-JSValue jsNumberCell(ExecState* exec, double d)
-{
- return new (exec) JSNumberCell(exec, d);
-}
-
-JSValue jsNumberCell(JSGlobalData* globalData, double d)
-{
- return new (globalData) JSNumberCell(globalData, d);
-}
-
-} // namespace JSC
-
-#else // USE(JSVALUE32)
-
// Keep our exported symbols lists happy.
namespace JSC {
@@ -105,4 +36,3 @@ JSValue jsNumberCell(ExecState*, double)
} // namespace JSC
-#endif // USE(JSVALUE32)
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index cdd2d8c..a25c531 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -35,167 +35,6 @@ namespace JSC {
extern const double NaN;
extern const double Inf;
-#if USE(JSVALUE32)
- JSValue jsNumberCell(ExecState*, double);
-
- class Identifier;
- class JSCell;
- class JSObject;
- class JSString;
- class PropertySlot;
-
- struct ClassInfo;
- struct Instruction;
-
- class JSNumberCell : public JSCell {
- friend class JIT;
- friend JSValue jsNumberCell(JSGlobalData*, double);
- friend JSValue jsNumberCell(ExecState*, double);
-
- public:
- double value() const { return m_value; }
-
- virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
- virtual bool toBoolean(ExecState*) const;
- virtual double toNumber(ExecState*) const;
- virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
-
- virtual JSObject* toThisObject(ExecState*) const;
- virtual JSValue getJSNumber();
-
- void* operator new(size_t size, ExecState* exec)
- {
- return exec->heap()->allocateNumber(size);
- }
-
- void* operator new(size_t size, JSGlobalData* globalData)
- {
- return globalData->heap.allocateNumber(size);
- }
-
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
-
- private:
- JSNumberCell(JSGlobalData* globalData, double value)
- : JSCell(globalData->numberStructure.get())
- , m_value(value)
- {
- }
-
- JSNumberCell(ExecState* exec, double value)
- : JSCell(exec->globalData().numberStructure.get())
- , m_value(value)
- {
- }
-
- virtual bool getUInt32(uint32_t&) const;
-
- double m_value;
- };
-
- JSValue jsNumberCell(JSGlobalData*, double);
-
- inline bool isNumberCell(JSValue v)
- {
- return v.isCell() && v.asCell()->isNumber();
- }
-
- inline JSNumberCell* asNumberCell(JSValue v)
- {
- ASSERT(isNumberCell(v));
- return static_cast<JSNumberCell*>(v.asCell());
- }
-
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState* exec, double d)
- {
- *this = jsNumberCell(exec, d);
- }
-
- inline JSValue::JSValue(ExecState* exec, double d)
- {
- JSValue v = JSImmediate::from(d);
- *this = v ? v : jsNumberCell(exec, d);
- }
-
- inline JSValue::JSValue(ExecState* exec, int i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, long long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned long long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, double d)
- {
- JSValue v = JSImmediate::from(d);
- *this = v ? v : jsNumberCell(globalData, d);
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, int i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(globalData, i);
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(globalData, i);
- }
-
- inline bool JSValue::isDouble() const
- {
- return isNumberCell(asValue());
- }
-
- inline double JSValue::asDouble() const
- {
- return asNumberCell(asValue())->value();
- }
-
- inline bool JSValue::isNumber() const
- {
- return JSImmediate::isNumber(asValue()) || isDouble();
- }
-
- inline double JSValue::uncheckedGetNumber() const
- {
- ASSERT(isNumber());
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
- }
-
-#endif // USE(JSVALUE32)
-
#if USE(JSVALUE64)
ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
{
@@ -295,7 +134,7 @@ namespace JSC {
#endif // USE(JSVALUE64)
-#if USE(JSVALUE32) || USE(JSVALUE64)
+#if USE(JSVALUE64)
inline JSValue::JSValue(ExecState*, char i)
{
@@ -351,7 +190,7 @@ namespace JSC {
return true;
}
-#endif // USE(JSVALUE32) || USE(JSVALUE64)
+#endif // USE(JSVALUE64)
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index ba50721..0794189 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -34,8 +34,8 @@
#include "LiteralParser.h"
#include "Lookup.h"
#include "PropertyNameArray.h"
-#include "StringBuilder.h"
-#include "StringConcatenate.h"
+#include "UStringBuilder.h"
+#include "UStringConcatenate.h"
#include <wtf/MathExtras.h>
namespace JSC {
@@ -85,7 +85,7 @@ private:
JSObject* object() const { return m_object; }
- bool appendNextProperty(Stringifier&, StringBuilder&);
+ bool appendNextProperty(Stringifier&, UStringBuilder&);
private:
JSObject* const m_object;
@@ -98,17 +98,17 @@ private:
friend class Holder;
- static void appendQuotedString(StringBuilder&, const UString&);
+ static void appendQuotedString(UStringBuilder&, const UString&);
JSValue toJSON(JSValue, const PropertyNameForFunctionCall&);
enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue };
- StringifyResult appendStringifiedValue(StringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
+ StringifyResult appendStringifiedValue(UStringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
bool willIndent() const;
void indent();
void unindent();
- void startNewLine(StringBuilder&) const;
+ void startNewLine(UStringBuilder&) const;
Stringifier* const m_nextStringifierToMark;
ExecState* const m_exec;
@@ -270,21 +270,21 @@ JSValue Stringifier::stringify(JSValue value)
PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value);
- StringBuilder result;
+ UStringBuilder result;
if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
return jsUndefined();
if (m_exec->hadException())
return jsNull();
- return jsString(m_exec, result.build());
+ return jsString(m_exec, result.toUString());
}
-void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
+void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value)
{
int length = value.length();
// String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters.
- builder.reserveCapacity(builder.size() + length + 2 + 8);
+ builder.reserveCapacity(builder.length() + length + 2 + 8);
builder.append('"');
@@ -361,7 +361,7 @@ inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionC
return call(m_exec, object, callType, callData, value, args);
}
-Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
+Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
{
// Call the toJSON function.
value = toJSON(value, propertyName);
@@ -466,7 +466,7 @@ inline void Stringifier::indent()
// Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
unsigned newSize = m_indent.length() + m_gap.length();
if (newSize > m_repeatedGap.length())
- m_repeatedGap = makeString(m_repeatedGap, m_gap);
+ m_repeatedGap = makeUString(m_repeatedGap, m_gap);
ASSERT(newSize <= m_repeatedGap.length());
m_indent = m_repeatedGap.substringSharingImpl(0, newSize);
}
@@ -477,7 +477,7 @@ inline void Stringifier::unindent()
m_indent = m_repeatedGap.substringSharingImpl(0, m_indent.length() - m_gap.length());
}
-inline void Stringifier::startNewLine(StringBuilder& builder) const
+inline void Stringifier::startNewLine(UStringBuilder& builder) const
{
if (m_gap.isEmpty())
return;
@@ -492,7 +492,7 @@ inline Stringifier::Holder::Holder(JSObject* object)
{
}
-bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBuilder& builder)
+bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBuilder& builder)
{
ASSERT(m_index <= m_size);
@@ -521,7 +521,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
// Last time through, finish up and return false.
if (m_index == m_size) {
stringifier.unindent();
- if (m_size && builder[builder.size() - 1] != '{')
+ if (m_size && builder[builder.length() - 1] != '{')
stringifier.startNewLine(builder);
builder.append(m_isArray ? ']' : '}');
return false;
@@ -562,7 +562,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
if (exec->hadException())
return false;
- rollBackPoint = builder.size();
+ rollBackPoint = builder.length();
// Append the separator string.
if (builder[rollBackPoint - 1] != '{')
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
index cabc428..30e40e4 100644
--- a/JavaScriptCore/runtime/JSObject.cpp
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -43,6 +43,8 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSObject);
+const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
+
static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
{
// Add properties from the static hashtables of properties
@@ -114,15 +116,19 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
+ if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
}
unsigned attributes;
JSCell* specificValue;
- if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly)
+ if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
+ if (slot.isStrictMode())
+ throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
return;
+ }
for (JSObject* obj = this; ; obj = asObject(prototype)) {
if (JSValue gs = obj->getDirect(propertyName)) {
@@ -151,7 +157,8 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
break;
}
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
+ if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -489,6 +496,11 @@ JSObject* JSObject::toThisObject(ExecState*) const
return const_cast<JSObject*>(this);
}
+JSValue JSObject::toStrictThisObject(ExecState*) const
+{
+ return const_cast<JSObject*>(this);
+}
+
JSObject* JSObject::unwrappedObject()
{
return this;
@@ -702,4 +714,9 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
return true;
}
+JSObject* throwTypeError(ExecState* exec, const UString& message)
+{
+ return throwError(exec, createTypeError(exec, message));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
index 4201703..8981469 100644
--- a/JavaScriptCore/runtime/JSObject.h
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -55,6 +55,9 @@ namespace JSC {
class Structure;
struct HashTable;
+ JSObject* throwTypeError(ExecState*, const UString&);
+ extern const char* StrictModeReadonlyPropertyWriteError;
+
// ECMA 262-3 8.6.1
// Property attributes
enum Attribute {
@@ -140,6 +143,7 @@ namespace JSC {
virtual JSObject* toObject(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
virtual JSObject* unwrappedObject();
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
@@ -175,9 +179,9 @@ namespace JSC {
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
- void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ bool putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
- void putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
+ bool putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
@@ -205,6 +209,7 @@ namespace JSC {
virtual bool isVariableObject() const { return false; }
virtual bool isActivationObject() const { return false; }
virtual bool isNotAnObjectErrorStub() const { return false; }
+ virtual bool isStrictModeFunction() const { return false; }
virtual ComplType exceptionType() const { return Throw; }
@@ -248,9 +253,6 @@ namespace JSC {
void getString(ExecState* exec);
void isObject();
void isString();
-#if USE(JSVALUE32)
- void isNumber();
-#endif
ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
@@ -265,8 +267,8 @@ namespace JSC {
return reinterpret_cast<JSValue*>(&propertyStorage()[offset]);
}
- void putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
- void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ bool putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
+ bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0);
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -299,9 +301,7 @@ inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure)
ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
ASSERT(m_structure->isEmpty());
ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0);
-#endif
}
inline JSObject::~JSObject()
@@ -450,7 +450,7 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
+inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -465,7 +465,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
m_structure->despecifyDictionaryFunction(propertyName);
if (checkReadOnly && currentAttributes & ReadOnly)
- return;
+ return false;
+
putDirectOffset(offset, value);
// At this point, the objects structure only has a specific value set if previously there
// had been one set, and if the new value being specified is the same (otherwise we would
@@ -475,7 +476,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// If there was previously a value, and the new value is the same, then we cannot cache.
if (!currentSpecificFunction || (specificFunction != currentSpecificFunction))
slot.setExistingProperty(this, offset);
- return;
+ return true;
}
size_t currentCapacity = m_structure->propertyStorageCapacity();
@@ -488,7 +489,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// See comment on setNewProperty call below.
if (!specificFunction)
slot.setNewProperty(this, offset);
- return;
+ return true;
}
size_t offset;
@@ -504,7 +505,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// so leave the slot in an uncachable state.
if (!specificFunction)
slot.setNewProperty(this, offset);
- return;
+ return true;
}
unsigned currentAttributes;
@@ -512,7 +513,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
- return;
+ return false;
// There are three possibilities here:
// (1) There is an existing specific value set, and we're overwriting with *the same value*.
@@ -527,7 +528,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// case (1) Do the put, then return leaving the slot uncachable.
if (specificFunction == currentSpecificFunction) {
putDirectOffset(offset, value);
- return;
+ return true;
}
// case (2) Despecify, fall through to (3).
setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
@@ -536,7 +537,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// case (3) set the slot, do the put, return.
slot.setExistingProperty(this, offset);
putDirectOffset(offset, value);
- return;
+ return true;
}
// If we have a specific function, we may have got to this point if there is
@@ -561,14 +562,15 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// so leave the slot in an uncachable state.
if (!specificFunction)
slot.setNewProperty(this, offset);
+ return true;
}
-inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
+ return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
}
inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
@@ -577,12 +579,12 @@ inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
+ return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
}
inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes)
@@ -591,9 +593,9 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, u
putDirectInternal(propertyName, value, attributes, false, slot, 0);
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- putDirectInternal(propertyName, value, 0, false, slot, 0);
+ return putDirectInternal(propertyName, value, 0, false, slot, 0);
}
inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
@@ -698,10 +700,11 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
asCell()->put(exec, propertyName, value, slot);
}
-inline void JSValue::putDirect(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(isCell() && isObject());
- asObject(asCell())->putDirect(propertyName, value, slot);
+ if (!asObject(asCell())->putDirect(propertyName, value, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
@@ -756,6 +759,13 @@ inline JSString* JSValue::toThisJSString(ExecState* exec) const
return isString() ? static_cast<JSString*>(asCell()) : jsString(exec, toThisObject(exec)->toString(exec));
}
+inline JSValue JSValue::toStrictThisObject(ExecState* exec) const
+{
+ if (!isObject())
+ return *this;
+ return asObject(asCell())->toStrictThisObject(exec);
+}
+
} // namespace JSC
#endif // JSObject_h
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index ad10218..7ab1d1c 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -42,6 +42,11 @@ JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
+JSValue JSStaticScopeObject::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
if (symbolTablePut(propertyName, value))
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h
index c0519c1..e69356a 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -53,6 +53,7 @@ namespace JSC{
virtual void markChildren(MarkStack&);
bool isDynamicScope(bool& requiresDynamicChecks) const;
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h
index 25fe685..49d4a63 100644
--- a/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/JavaScriptCore/runtime/JSStringBuilder.h
@@ -28,7 +28,7 @@
#include "ExceptionHelpers.h"
#include "JSString.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include "Vector.h"
namespace JSC {
@@ -87,7 +87,7 @@ protected:
template<typename StringType1, typename StringType2>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -96,7 +96,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -105,7 +105,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -114,7 +114,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -123,7 +123,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index b5834c1..b5dcbec 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -80,7 +80,7 @@ namespace JSC {
public:
static EncodedJSValue encode(JSValue value);
static JSValue decode(EncodedJSValue ptr);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
private:
static JSValue makeImmediate(intptr_t value);
intptr_t immediateValue();
@@ -193,6 +193,7 @@ namespace JSC {
bool needsThisConversion() const;
JSObject* toThisObject(ExecState*) const;
+ JSValue toStrictThisObject(ExecState*) const;
UString toThisString(ExecState*) const;
JSString* toThisJSString(ExecState*) const;
diff --git a/JavaScriptCore/runtime/JSZombie.h b/JavaScriptCore/runtime/JSZombie.h
index 711f673..da45699 100644
--- a/JavaScriptCore/runtime/JSZombie.h
+++ b/JavaScriptCore/runtime/JSZombie.h
@@ -60,6 +60,7 @@ public:
virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; }
virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; }
virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
+ virtual JSValue toStrictThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return JSValue(); }
virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); }
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp
index cc33bae..f1df15f 100644
--- a/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/JavaScriptCore/runtime/LiteralParser.cpp
@@ -29,7 +29,7 @@
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -135,7 +135,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
{
++m_ptr;
const UChar* runStart;
- StringBuilder builder;
+ UStringBuilder builder;
do {
runStart = m_ptr;
while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
@@ -200,7 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (m_ptr >= m_end || *m_ptr != '"')
return TokError;
- token.stringToken = builder.build();
+ token.stringToken = builder.toUString();
token.type = TokString;
token.end = ++m_ptr;
return TokString;
diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h
index 6c18cdd..e82b593 100644
--- a/JavaScriptCore/runtime/NumberObject.h
+++ b/JavaScriptCore/runtime/NumberObject.h
@@ -37,11 +37,7 @@ namespace JSC {
}
protected:
-#if USE(JSVALUE32)
- static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
-#else
static const unsigned StructureFlags = JSWrapperObject::StructureFlags;
-#endif
private:
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index e18553b..4a2ca74 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -25,10 +25,8 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
-#include "JSStringBuilder.h"
#include "Operations.h"
#include "PrototypeFunction.h"
-#include "StringBuilder.h"
#include "dtoa.h"
#include <wtf/Assertions.h>
#include <wtf/DecimalNumber.h>
@@ -119,8 +117,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
// Round if the argument is not undefined, always format as exponential.
NumberToStringBuffer buffer;
unsigned length = isUndefined
- ? DecimalNumber(x).toStringExponential(buffer)
- : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer);
+ ? DecimalNumber(x).toStringExponential(buffer, WTF::NumberToStringBufferLength)
+ : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
@@ -156,7 +154,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
// Convert to decimal with rounding, and format as decimal.
NumberToStringBuffer buffer;
- unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer);
+ unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
@@ -198,8 +196,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
// 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c)
NumberToStringBuffer buffer;
unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures
- ? number.toStringDecimal(buffer)
- : number.toStringExponential(buffer);
+ ? number.toStringDecimal(buffer, WTF::NumberToStringBufferLength)
+ : number.toStringExponential(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index eed1f16..9226953 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -460,7 +460,7 @@ namespace JSC {
}
}
- ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+ ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut)
{
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator next = iter;
@@ -472,7 +472,9 @@ namespace JSC {
JSObject* base;
while (true) {
base = *iter;
- if (next == end || base->getPropertySlot(callFrame, property, slot))
+ if (next == end)
+ return isStrictPut ? JSValue() : base;
+ if (base->getPropertySlot(callFrame, property, slot))
return base;
iter = next;
diff --git a/JavaScriptCore/runtime/PutPropertySlot.h b/JavaScriptCore/runtime/PutPropertySlot.h
index eb8ea8a..4b0b394 100644
--- a/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/JavaScriptCore/runtime/PutPropertySlot.h
@@ -38,9 +38,10 @@ namespace JSC {
public:
enum Type { Uncachable, ExistingProperty, NewProperty };
- PutPropertySlot()
+ PutPropertySlot(bool isStrictMode = false)
: m_type(Uncachable)
, m_base(0)
+ , m_isStrictMode(isStrictMode)
{
}
@@ -61,6 +62,7 @@ namespace JSC {
Type type() const { return m_type; }
JSObject* base() const { return m_base; }
+ bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
size_t cachedOffset() const {
ASSERT(isCacheable());
@@ -70,6 +72,7 @@ namespace JSC {
Type m_type;
JSObject* m_base;
size_t m_offset;
+ bool m_isStrictMode;
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index 214e528..b9aa587 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -35,7 +35,7 @@
#include "RegExpPrototype.h"
#include "RegExp.h"
#include "RegExpCache.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <wtf/PassOwnPtr.h>
namespace JSC {
@@ -307,7 +307,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
if (!regExp->isValid())
- return throwError(exec, createSyntaxError(exec, makeString("Invalid regular expression: ", regExp->errorMessage())));
+ return throwError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage())));
return new (exec) RegExpObject(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
}
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
index 4462879..7d14814 100644
--- a/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -29,7 +29,7 @@
#include "Lookup.h"
#include "RegExpConstructor.h"
#include "RegExpPrototype.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <wtf/PassOwnPtr.h>
namespace JSC {
@@ -146,7 +146,7 @@ bool RegExpObject::match(ExecState* exec)
UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec);
if (input.isNull()) {
- throwError(exec, createError(exec, makeString("No input to ", toString(exec), ".")));
+ throwError(exec, createError(exec, makeUString("No input to ", toString(exec), ".")));
return false;
}
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index d66f5d7..0a4c8bf 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -34,6 +34,7 @@
#include "RegExpObject.h"
#include "RegExp.h"
#include "RegExpCache.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -94,7 +95,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
}
if (!regExp->isValid())
- return throwVMError(exec, createSyntaxError(exec, makeString("Invalid regular expression: ", regExp->errorMessage())));
+ return throwVMError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage())));
asRegExpObject(thisValue)->setRegExp(regExp.release());
asRegExpObject(thisValue)->setLastIndex(0);
diff --git a/JavaScriptCore/runtime/StrictEvalActivation.cpp b/JavaScriptCore/runtime/StrictEvalActivation.cpp
new file mode 100644
index 0000000..5bb013b
--- /dev/null
+++ b/JavaScriptCore/runtime/StrictEvalActivation.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StrictEvalActivation.h"
+
+namespace JSC {
+
+StrictEvalActivation::StrictEvalActivation(ExecState* exec)
+ : JSObject(exec->globalData().strictEvalActivationStructure)
+{
+}
+
+bool StrictEvalActivation::deleteProperty(ExecState*, const Identifier&)
+{
+ return false;
+}
+
+JSObject* StrictEvalActivation::toThisObject(ExecState* exec) const
+{
+ return exec->globalThisValue();
+}
+
+JSValue StrictEvalActivation::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
+}
diff --git a/JavaScriptCore/runtime/StrictEvalActivation.h b/JavaScriptCore/runtime/StrictEvalActivation.h
new file mode 100644
index 0000000..1385eec
--- /dev/null
+++ b/JavaScriptCore/runtime/StrictEvalActivation.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StrictEvalActivation_h
+#define StrictEvalActivation_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class StrictEvalActivation : public JSObject {
+public:
+ StrictEvalActivation(ExecState*);
+ virtual bool deleteProperty(ExecState*, const Identifier&);
+ virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
+};
+
+} // namespace JSC
+
+#endif // StrictEvalActivation_h
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index 91e9b06..37436f9 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -206,7 +206,8 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
substitutedReplacement.append(replacement.characters() + offset, i - offset);
i += 1 + advance;
offset = i + 1;
- substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
+ if (backrefStart >= 0)
+ substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
} while ((i = replacement.find('$', i + 1)) != notFound);
if (replacement.length() - offset)
@@ -275,12 +276,16 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J
int bufferPos = 0;
for (int i = 0; i < maxCount; i++) {
if (i < rangeCount) {
- StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, substringRanges[i].length);
- bufferPos += substringRanges[i].length;
+ if (int srcLen = substringRanges[i].length) {
+ StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, srcLen);
+ bufferPos += srcLen;
+ }
}
if (i < separatorCount) {
- StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), separators[i].length());
- bufferPos += separators[i].length();
+ if (int sepLen = separators[i].length()) {
+ StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), sepLen);
+ bufferPos += sepLen;
+ }
}
}
@@ -302,6 +307,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (pattern.inherits(&RegExpObject::info)) {
const UString& source = sourceVal->value(exec);
+ unsigned sourceLen = source.length();
if (exec->hadException())
return JSValue::encode(JSValue());
RegExp* reg = asRegExpObject(pattern)->regExp();
@@ -330,7 +336,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
break;
-
+
sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
int completeMatchStart = ovector[0];
@@ -347,7 +353,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
cachedCall.setArgument(i++, jsNumber(exec, completeMatchStart));
cachedCall.setArgument(i++, sourceVal);
-
+
cachedCall.setThis(exec->globalThisValue());
JSValue result = cachedCall.call();
if (LIKELY(result.isString()))
@@ -363,10 +369,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
// special case of empty match
if (matchLen == 0) {
startPosition++;
- if (startPosition > source.length())
+ if (startPosition > sourceLen)
break;
}
- }
+ }
} else {
do {
int matchIndex;
@@ -376,16 +382,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (matchIndex < 0)
break;
- sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
-
if (callType != CallTypeNone) {
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
int completeMatchStart = ovector[0];
MarkedArgumentBuffer args;
for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
int matchStart = ovector[i * 2];
int matchLen = ovector[i * 2 + 1] - matchStart;
-
+
if (matchStart < 0)
args.append(jsUndefined());
else
@@ -398,8 +404,17 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
if (exec->hadException())
break;
- } else
- replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+ } else {
+ int replLen = replacementString.length();
+ if (lastIndex < matchIndex || replLen) {
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
+ if (replLen)
+ replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+ else
+ replacements.append(UString());
+ }
+ }
lastIndex = matchIndex + matchLen;
startPosition = lastIndex;
@@ -407,7 +422,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
// special case of empty match
if (matchLen == 0) {
startPosition++;
- if (startPosition > source.length())
+ if (startPosition > sourceLen)
break;
}
} while (global);
@@ -416,8 +431,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (!lastIndex && replacements.isEmpty())
return JSValue::encode(sourceVal);
- if (static_cast<unsigned>(lastIndex) < source.length())
- sourceRanges.append(StringRange(lastIndex, source.length() - lastIndex));
+ if (static_cast<unsigned>(lastIndex) < sourceLen)
+ sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex));
return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
}
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/UStringBuilder.h
index 27aa57f..31ccf38 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/UStringBuilder.h
@@ -23,65 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StringBuilder_h
-#define StringBuilder_h
+#ifndef UStringBuilder_h
+#define UStringBuilder_h
-#include <wtf/Vector.h>
+#include <wtf/text/StringBuilder.h>
namespace JSC {
-class StringBuilder {
+class UStringBuilder : public StringBuilder {
public:
- void append(const UChar u)
- {
- buffer.append(u);
- }
+ using StringBuilder::append;
+ void append(const UString& str) { append(String(str.impl())); }
- void append(const char* str)
- {
- append(str, strlen(str));
- }
-
- void append(const char* str, size_t len)
- {
- reserveCapacity(buffer.size() + len);
- for (size_t i = 0; i < len; i++)
- buffer.append(static_cast<unsigned char>(str[i]));
- }
-
- void append(const UChar* str, size_t len)
- {
- buffer.append(str, len);
- }
-
- void append(const UString& str)
- {
- buffer.append(str.characters(), str.length());
- }
-
- bool isEmpty() { return buffer.isEmpty(); }
- void reserveCapacity(size_t newCapacity)
- {
- if (newCapacity < buffer.capacity())
- return;
- buffer.reserveCapacity(std::max(newCapacity, buffer.capacity() + buffer.capacity() / 4 + 1));
- }
- void resize(size_t size) { buffer.resize(size); }
- size_t size() const { return buffer.size(); }
-
- UChar operator[](size_t i) const { return buffer.at(i); }
-
- UString build()
- {
- buffer.shrinkToFit();
- ASSERT(buffer.data() || !buffer.size());
- return UString::adopt(buffer);
- }
-
-protected:
- Vector<UChar, 64> buffer;
+ UString toUString() { return toString().impl(); }
};
-}
+} // namespace JSC
-#endif
+#endif // UStringBuilder_h
diff --git a/JavaScriptCore/runtime/UStringConcatenate.h b/JavaScriptCore/runtime/UStringConcatenate.h
new file mode 100644
index 0000000..0990c72
--- /dev/null
+++ b/JavaScriptCore/runtime/UStringConcatenate.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UStringConcatenate_h
+#define UStringConcatenate_h
+
+#include "UString.h"
+#include <wtf/text/StringConcatenate.h>
+
+namespace WTF {
+
+template<>
+class StringTypeAdapter<JSC::UString> {
+public:
+ StringTypeAdapter<JSC::UString>(JSC::UString& string)
+ : m_data(string.characters())
+ , m_length(string.length())
+ {
+ }
+
+ unsigned length() { return m_length; }
+
+ void writeTo(UChar* destination)
+ {
+ for (unsigned i = 0; i < m_length; ++i)
+ destination[i] = m_data[i];
+ }
+
+private:
+ const UChar* m_data;
+ unsigned m_length;
+};
+
+}; // namespace WTF
+
+namespace JSC {
+
+template<typename StringType1, typename StringType2>
+UString makeUString(StringType1 string1, StringType2 string2)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6, string7);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
+UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+{
+ PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+}
+
+} // namespace JSC
+
+#endif
diff --git a/JavaScriptCore/jsc/CMakeLists.txt b/JavaScriptCore/shell/CMakeLists.txt
index 1f529a5..1f529a5 100644
--- a/JavaScriptCore/jsc/CMakeLists.txt
+++ b/JavaScriptCore/shell/CMakeLists.txt
diff --git a/JavaScriptCore/jsc/CMakeListsEfl.txt b/JavaScriptCore/shell/CMakeListsEfl.txt
index 58d44f4..58d44f4 100644
--- a/JavaScriptCore/jsc/CMakeListsEfl.txt
+++ b/JavaScriptCore/shell/CMakeListsEfl.txt
diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript
index d85364c..8d7f69c 100644
--- a/JavaScriptCore/wscript
+++ b/JavaScriptCore/wscript
@@ -75,10 +75,10 @@ def build(bld):
install_path = output_dir,
)
- # we'll get an error if exceptions are on because of an unwind error when using __try
if building_on_win32:
- flags = obj.env.CXXFLAGS
- flags.remove('/EHsc')
- obj.env.CXXFLAGS = flags
+ myenv = obj.env.copy()
+ myenv.CXXFLAGS = myenv.CXXFLAGS[:]
+ myenv.CXXFLAGS.remove('/EHsc')
+ obj.env = myenv
bld.install_files(os.path.join(output_dir, 'JavaScriptCore'), 'API/*.h')
diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt
index 896794e..898d19b 100644
--- a/JavaScriptCore/wtf/CMakeLists.txt
+++ b/JavaScriptCore/wtf/CMakeLists.txt
@@ -2,6 +2,7 @@ SET(WTF_SOURCES
Assertions.cpp
ByteArray.cpp
CurrentTime.cpp
+ DecimalNumber.cpp
FastMalloc.cpp
HashTable.cpp
MainThread.cpp
@@ -16,6 +17,7 @@ SET(WTF_SOURCES
text/AtomicString.cpp
text/CString.cpp
+ text/StringBuilder.cpp
text/StringImpl.cpp
text/StringStatics.cpp
text/WTFString.cpp
diff --git a/JavaScriptCore/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt
index 6a714ae..e5d8bd7 100644
--- a/JavaScriptCore/wtf/CMakeListsEfl.txt
+++ b/JavaScriptCore/wtf/CMakeListsEfl.txt
@@ -1,4 +1,10 @@
-ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1)
+IF (ENABLE_FAST_MALLOC)
+ LIST(APPEND WTF_SOURCES
+ TCSystemAlloc.cpp
+ )
+ELSE ()
+ ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1)
+ENDIF()
LIST(APPEND WTF_SOURCES
efl/MainThreadEfl.cpp
@@ -16,7 +22,12 @@ IF (ENABLE_GLIB_SUPPORT)
)
LIST(APPEND WTF_INCLUDE_DIRECTORIES
- ${JAVASCRIPTCORE_DIR}/wtf/gobject
+ ${Glib_INCLUDE_DIRS}
+ ${JAVASCRIPTCORE_DIR}/wtf/gobject
+ )
+
+ LIST(APPEND WTF_LIBRARIES
+ ${Glib_LIBRARIES}
)
ENDIF ()
diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h
index dcb1f6c..7119656 100644
--- a/JavaScriptCore/wtf/CurrentTime.h
+++ b/JavaScriptCore/wtf/CurrentTime.h
@@ -61,6 +61,7 @@ namespace WTF {
} // namespace WTF
using WTF::currentTime;
+using WTF::currentTimeMS;
using WTF::getLocalTime;
#endif // CurrentTime_h
diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp
index b9a0207..d005859 100644
--- a/JavaScriptCore/wtf/DateMath.cpp
+++ b/JavaScriptCore/wtf/DateMath.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
@@ -479,7 +480,7 @@ void initializeDates()
equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
}
-static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
+static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, double second)
{
double days = (day - 32075)
+ floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
@@ -557,6 +558,162 @@ static bool parseLong(const char* string, char** stopPosition, int base, long* r
return true;
}
+double parseES5DateFromNullTerminatedCharacters(const char* dateString)
+{
+ // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15
+ // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z).
+ // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace).
+
+ static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ const char* currentPosition = dateString;
+ char* postParsePosition;
+
+ // This is a bit more lenient on the year string than ES5 specifies:
+ // instead of restricting to 4 digits (or 6 digits with mandatory +/-),
+ // it accepts any integer value. Consider this an implementation fallback.
+ long year;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &year))
+ return NaN;
+ if (*postParsePosition != '-')
+ return NaN;
+ currentPosition = postParsePosition + 1;
+
+ long month;
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &month))
+ return NaN;
+ if (*postParsePosition != '-' || (postParsePosition - currentPosition) != 2)
+ return NaN;
+ currentPosition = postParsePosition + 1;
+
+ long day;
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &day))
+ return NaN;
+ if (*postParsePosition != 'T' || (postParsePosition - currentPosition) != 2)
+ return NaN;
+ currentPosition = postParsePosition + 1;
+
+ long hours;
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &hours))
+ return NaN;
+ if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
+ return NaN;
+ currentPosition = postParsePosition + 1;
+
+ long minutes;
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &minutes))
+ return NaN;
+ if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
+ return NaN;
+ currentPosition = postParsePosition + 1;
+
+ long intSeconds;
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &intSeconds))
+ return NaN;
+ if ((postParsePosition - currentPosition) != 2)
+ return NaN;
+
+ double seconds = intSeconds;
+ if (*postParsePosition == '.') {
+ currentPosition = postParsePosition + 1;
+
+ // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but
+ // a reasonable interpretation guided by the given examples and RFC 3339 says "no".
+ // We check the next character to avoid reading +/- timezone hours after an invalid decimal.
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+
+ // We are more lenient than ES5 by accepting more or less than 3 fraction digits.
+ long fracSeconds;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds))
+ return NaN;
+
+ long numFracDigits = postParsePosition - currentPosition;
+ seconds += fracSeconds * pow(10.0, static_cast<double>(-numFracDigits));
+ }
+ currentPosition = postParsePosition;
+
+ // A few of these checks could be done inline above, but since many of them are interrelated
+ // we would be sacrificing readability to "optimize" the (presumably less common) failure path.
+ if (month < 1 || month > 12)
+ return NaN;
+ if (day < 1 || day > daysPerMonth[month - 1])
+ return NaN;
+ if (month == 2 && day > 28 && !isLeapYear(year))
+ return NaN;
+ if (hours < 0 || hours > 24)
+ return NaN;
+ if (hours == 24 && (minutes || seconds))
+ return NaN;
+ if (minutes < 0 || minutes > 59)
+ return NaN;
+ if (seconds < 0 || seconds >= 61)
+ return NaN;
+ if (seconds > 60) {
+ // Discard leap seconds by clamping to the end of a minute.
+ seconds = 60;
+ }
+
+ long timeZoneSeconds = 0;
+ if (*currentPosition != 'Z') {
+ bool tzNegative;
+ if (*currentPosition == '-')
+ tzNegative = true;
+ else if (*currentPosition == '+')
+ tzNegative = false;
+ else
+ return NaN;
+ currentPosition += 1;
+
+ long tzHours;
+ long tzHoursAbs;
+ long tzMinutes;
+
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours))
+ return NaN;
+ if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
+ return NaN;
+ tzHoursAbs = abs(tzHours);
+ currentPosition = postParsePosition + 1;
+
+ if (!isASCIIDigit(*currentPosition))
+ return NaN;
+ if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes))
+ return NaN;
+ if ((postParsePosition - currentPosition) != 2)
+ return NaN;
+ currentPosition = postParsePosition;
+
+ if (tzHoursAbs > 24)
+ return NaN;
+ if (tzMinutes < 0 || tzMinutes > 59)
+ return NaN;
+
+ timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs));
+ if (tzNegative)
+ timeZoneSeconds = -timeZoneSeconds;
+ } else {
+ currentPosition += 1;
+ }
+ if (*currentPosition)
+ return NaN;
+
+ double dateSeconds = ymdhmsToSeconds(year, month, day, hours, minutes, seconds) - timeZoneSeconds;
+ return dateSeconds * msPerSecond;
+}
+
// Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
static double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset)
{
diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h
index 033d25e..be51947 100644
--- a/JavaScriptCore/wtf/DateMath.h
+++ b/JavaScriptCore/wtf/DateMath.h
@@ -53,7 +53,8 @@ namespace WTF {
void initializeDates();
int equivalentYearForDST(int year);
-// Not really math related, but this is currently the only shared place to put these.
+// Not really math related, but this is currently the only shared place to put these.
+double parseES5DateFromNullTerminatedCharacters(const char* dateString);
double parseDateFromNullTerminatedCharacters(const char* dateString);
double timeClip(double);
@@ -94,6 +95,7 @@ using WTF::msPerDay;
using WTF::msPerSecond;
using WTF::msToYear;
using WTF::secondsPerMinute;
+using WTF::parseDateFromNullTerminatedCharacters;
#if USE(JSC)
namespace JSC {
diff --git a/JavaScriptCore/wtf/DecimalNumber.cpp b/JavaScriptCore/wtf/DecimalNumber.cpp
new file mode 100644
index 0000000..70304e2
--- /dev/null
+++ b/JavaScriptCore/wtf/DecimalNumber.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DecimalNumber.h"
+#include <math.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace WTF {
+
+unsigned DecimalNumber::bufferLengthForStringDecimal() const
+{
+ unsigned length = 0;
+ // if the exponent is negative the number decimal representation is of the form:
+ // [<sign>]0.[<zeros>]<significand>
+ if (m_exponent < 0) {
+ if (m_sign)
+ ++length;
+ length += 2; // for "0."
+ length += -m_exponent - 1;
+ length += m_precision;
+ return length;
+ }
+
+ unsigned digitsBeforeDecimalPoint = m_exponent + 1;
+
+ // If the precision is <= than the number of digits to get up to the decimal
+ // point, then there is no fractional part, number is of the form:
+ // [<sign>]<significand>[<zeros>]
+ if (m_precision <= digitsBeforeDecimalPoint) {
+ if (m_sign)
+ ++length;
+ length += m_precision;
+ length += digitsBeforeDecimalPoint - m_precision;
+ return length;
+ }
+
+ // If we get here, number starts before the decimal point, and ends after it,
+ // as such is of the form:
+ // [<sign>]<significand-begin>.<significand-end>
+ if (m_sign)
+ ++length;
+ length += digitsBeforeDecimalPoint;
+ ++length; // for decimal point
+ length += m_precision - digitsBeforeDecimalPoint;
+
+ return length;
+}
+
+unsigned DecimalNumber::bufferLengthForStringExponential() const
+{
+ unsigned length = 0;
+ if (m_sign)
+ ++length;
+
+ // Add the significand
+ ++length;
+
+ if (m_precision > 1) {
+ ++length; // for decimal point
+ length += m_precision - 1;
+ }
+
+ // Add "e+" or "e-"
+ length += 2;
+
+ int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent;
+
+ // Add the exponent
+ if (exponent >= 100)
+ ++length;
+ if (exponent >= 10)
+ ++length;
+ ++length;
+
+ return length;
+}
+
+unsigned DecimalNumber::toStringDecimal(UChar* buffer, unsigned bufferLength) const
+{
+ ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal());
+
+ // Should always be at least one digit to add to the string!
+ ASSERT(m_precision);
+ UChar* next = buffer;
+
+ // if the exponent is negative the number decimal representation is of the form:
+ // [<sign>]0.[<zeros>]<significand>
+ if (m_exponent < 0) {
+ unsigned zeros = -m_exponent - 1;
+
+ if (m_sign)
+ *next++ = '-';
+ *next++ = '0';
+ *next++ = '.';
+ for (unsigned i = 0; i < zeros; ++i)
+ *next++ = '0';
+ for (unsigned i = 0; i < m_precision; ++i)
+ *next++ = m_significand[i];
+
+ return next - buffer;
+ }
+
+ unsigned digitsBeforeDecimalPoint = m_exponent + 1;
+
+ // If the precision is <= than the number of digits to get up to the decimal
+ // point, then there is no fractional part, number is of the form:
+ // [<sign>]<significand>[<zeros>]
+ if (m_precision <= digitsBeforeDecimalPoint) {
+ if (m_sign)
+ *next++ = '-';
+ for (unsigned i = 0; i < m_precision; ++i)
+ *next++ = m_significand[i];
+ for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
+ *next++ = '0';
+
+ return next - buffer;
+ }
+
+ // If we get here, number starts before the decimal point, and ends after it,
+ // as such is of the form:
+ // [<sign>]<significand-begin>.<significand-end>
+
+ if (m_sign)
+ *next++ = '-';
+ for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
+ *next++ = m_significand[i];
+ *next++ = '.';
+ for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
+ *next++ = m_significand[i];
+
+ return next - buffer;
+}
+
+unsigned DecimalNumber::toStringExponential(UChar* buffer, unsigned bufferLength) const
+{
+ ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential());
+
+ // Should always be at least one digit to add to the string!
+ ASSERT(m_precision);
+ UChar* next = buffer;
+
+ // Add the sign
+ if (m_sign)
+ *next++ = '-';
+
+ // Add the significand
+ *next++ = m_significand[0];
+ if (m_precision > 1) {
+ *next++ = '.';
+ for (unsigned i = 1; i < m_precision; ++i)
+ *next++ = m_significand[i];
+ }
+
+ // Add "e+" or "e-"
+ *next++ = 'e';
+ int exponent;
+ if (m_exponent >= 0) {
+ *next++ = '+';
+ exponent = m_exponent;
+ } else {
+ *next++ = '-';
+ exponent = -m_exponent;
+ }
+
+ // Add the exponent
+ if (exponent >= 100)
+ *next++ = '0' + exponent / 100;
+ if (exponent >= 10)
+ *next++ = '0' + (exponent % 100) / 10;
+ *next++ = '0' + exponent % 10;
+
+ return next - buffer;
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h
index 3a831b7..c42f00b 100644
--- a/JavaScriptCore/wtf/DecimalNumber.h
+++ b/JavaScriptCore/wtf/DecimalNumber.h
@@ -81,104 +81,16 @@ public:
ASSERT(m_significand[0] != '0' || !m_exponent);
}
- unsigned toStringDecimal(NumberToStringBuffer buffer)
- {
- // Should always be at least one digit to add to the string!
- ASSERT(m_precision);
- UChar* next = buffer;
-
- // if the exponent is negative the number decimal representation is of the form:
- // [<sign>]0.[<zeros>]<significand>
- if (m_exponent < 0) {
- unsigned zeros = -m_exponent - 1;
-
- if (m_sign)
- *next++ = '-';
- *next++ = '0';
- *next++ = '.';
- for (unsigned i = 0; i < zeros; ++i)
- *next++ = '0';
- for (unsigned i = 0; i < m_precision; ++i)
- *next++ = m_significand[i];
-
- return next - buffer;
- }
-
- unsigned digitsBeforeDecimalPoint = m_exponent + 1;
-
- // If the precision is <= than the number of digits to get up to the decimal
- // point, then there is no fractional part, number is of the form:
- // [<sign>]<significand>[<zeros>]
- if (m_precision <= digitsBeforeDecimalPoint) {
- if (m_sign)
- *next++ = '-';
- for (unsigned i = 0; i < m_precision; ++i)
- *next++ = m_significand[i];
- for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
- *next++ = '0';
-
- return next - buffer;
- }
-
- // If we get here, number starts before the decimal point, and ends after it,
- // as such is of the form:
- // [<sign>]<significand-begin>.<significand-end>
-
- if (m_sign)
- *next++ = '-';
- for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
- *next++ = m_significand[i];
- *next++ = '.';
- for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
- *next++ = m_significand[i];
-
- return next - buffer;
- }
+ unsigned bufferLengthForStringDecimal() const;
+ unsigned bufferLengthForStringExponential() const;
- unsigned toStringExponential(NumberToStringBuffer buffer)
- {
- // Should always be at least one digit to add to the string!
- ASSERT(m_precision);
-
- UChar* next = buffer;
-
- // Add the sign
- if (m_sign)
- *next++ = '-';
-
- // Add the significand
- *next++ = m_significand[0];
- if (m_precision > 1) {
- *next++ = '.';
- for (unsigned i = 1; i < m_precision; ++i)
- *next++ = m_significand[i];
- }
-
- // Add "e+" or "e-"
- *next++ = 'e';
- int exponent;
- if (m_exponent >= 0) {
- *next++ = '+';
- exponent = m_exponent;
- } else {
- *next++ = '-';
- exponent = -m_exponent;
- }
-
- // Add the exponent
- if (exponent >= 100)
- *next++ = '0' + exponent / 100;
- if (exponent >= 10)
- *next++ = '0' + (exponent % 100) / 10;
- *next++ = '0' + exponent % 10;
-
- return next - buffer;
- }
+ unsigned toStringDecimal(UChar* buffer, unsigned bufferLength) const;
+ unsigned toStringExponential(UChar* buffer, unsigned bufferLength) const;
- bool sign() { return m_sign; }
- int exponent() { return m_exponent; }
- const char* significand() { return m_significand; } // significand contains precision characters, is not null-terminated.
- unsigned precision() { return m_precision; }
+ bool sign() const { return m_sign; }
+ int exponent() const { return m_exponent; }
+ const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
+ unsigned precision() const { return m_precision; }
private:
bool m_sign;
diff --git a/JavaScriptCore/wtf/FastAllocBase.h b/JavaScriptCore/wtf/FastAllocBase.h
index 81b1de0..bb1825e 100644
--- a/JavaScriptCore/wtf/FastAllocBase.h
+++ b/JavaScriptCore/wtf/FastAllocBase.h
@@ -85,38 +85,41 @@
namespace WTF {
- class FastAllocBase {
- public:
- // Placement operator new.
- void* operator new(size_t, void* p) { return p; }
- void* operator new[](size_t, void* p) { return p; }
-
- void* operator new(size_t size)
- {
- void* p = fastMalloc(size);
- fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNew);
- return p;
- }
-
- void operator delete(void* p)
- {
- fastMallocMatchValidateFree(p, Internal::AllocTypeClassNew);
- fastFree(p);
- }
-
- void* operator new[](size_t size)
- {
- void* p = fastMalloc(size);
- fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNewArray);
- return p;
- }
-
- void operator delete[](void* p)
- {
- fastMallocMatchValidateFree(p, Internal::AllocTypeClassNewArray);
- fastFree(p);
- }
- };
+#define WTF_MAKE_FAST_ALLOCATED \
+public: \
+ void* operator new(size_t, void* p) { return p; } \
+ void* operator new[](size_t, void* p) { return p; } \
+ \
+ void* operator new(size_t size) \
+ { \
+ void* p = ::WTF::fastMalloc(size); \
+ ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \
+ return p; \
+ } \
+ \
+ void operator delete(void* p) \
+ { \
+ ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \
+ ::WTF::fastFree(p); \
+ } \
+ \
+ void* operator new[](size_t size) \
+ { \
+ void* p = ::WTF::fastMalloc(size); \
+ ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \
+ return p; \
+ } \
+ \
+ void operator delete[](void* p) \
+ { \
+ ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \
+ ::WTF::fastFree(p); \
+ } \
+private:
+
+class FastAllocBase {
+ WTF_MAKE_FAST_ALLOCATED
+};
// fastNew / fastDelete
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 1e537b9..bbbdaf2 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -2185,10 +2185,10 @@ class TCMalloc_ThreadCache {
// Total byte size in cache
size_t Size() const { return size_; }
- void* Allocate(size_t size);
+ ALWAYS_INLINE void* Allocate(size_t size);
void Deallocate(void* ptr, size_t size_class);
- void FetchFromCentralCache(size_t cl, size_t allocationSize);
+ ALWAYS_INLINE void FetchFromCentralCache(size_t cl, size_t allocationSize);
void ReleaseToCentralCache(size_t cl, int N);
void Scavenge();
void Print() const;
@@ -2289,12 +2289,12 @@ class TCMalloc_Central_FreeList {
// REQUIRES: lock_ is held
// Release an object to spans.
// May temporarily release lock_.
- void ReleaseToSpans(void* object);
+ ALWAYS_INLINE void ReleaseToSpans(void* object);
// REQUIRES: lock_ is held
// Populate cache by fetching from the page heap.
// May temporarily release lock_.
- void Populate();
+ ALWAYS_INLINE void Populate();
// REQUIRES: lock is held.
// Tries to make room for a TCEntry. If the cache is full it will try to
@@ -2307,7 +2307,7 @@ class TCMalloc_Central_FreeList {
// just iterates over the sizeclasses but does so without taking a lock.
// Returns true on success.
// May temporarily lock a "random" size class.
- static bool EvictRandomSizeClass(size_t locked_size_class, bool force);
+ static ALWAYS_INLINE bool EvictRandomSizeClass(size_t locked_size_class, bool force);
// REQUIRES: lock_ is *not* held.
// Tries to shrink the Cache. If force is true it will relase objects to
@@ -3705,7 +3705,7 @@ extern "C"
#define do_malloc do_malloc<crashOnFailure>
template <bool crashOnFailure>
-void* malloc(size_t);
+ALWAYS_INLINE void* malloc(size_t);
void* fastMalloc(size_t size)
{
@@ -3766,7 +3766,7 @@ void free(void* ptr) {
extern "C"
#else
template <bool crashOnFailure>
-void* calloc(size_t, size_t);
+ALWAYS_INLINE void* calloc(size_t, size_t);
void* fastCalloc(size_t n, size_t elem_size)
{
@@ -3830,7 +3830,7 @@ void cfree(void* ptr) {
extern "C"
#else
template <bool crashOnFailure>
-void* realloc(void*, size_t);
+ALWAYS_INLINE void* realloc(void*, size_t);
void* fastRealloc(void* old_ptr, size_t new_size)
{
diff --git a/JavaScriptCore/wtf/MD5.cpp b/JavaScriptCore/wtf/MD5.cpp
index 375446e..c926a7b 100644
--- a/JavaScriptCore/wtf/MD5.cpp
+++ b/JavaScriptCore/wtf/MD5.cpp
@@ -76,7 +76,7 @@ static void expectMD5(CString input, CString expected)
snprintf(buf, 3, "%02x", digest.at(i));
buf += 2;
}
- ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%d] actual:%s expected:%s", input.data(), input.length(), actual.data(), expected.data());
+ ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%lu] actual:%s expected:%s", input.data(), static_cast<unsigned long>(input.length()), actual.data(), expected.data());
}
static void testMD5()
diff --git a/JavaScriptCore/wtf/Noncopyable.h b/JavaScriptCore/wtf/Noncopyable.h
index 898c1ba..285ed2e 100644
--- a/JavaScriptCore/wtf/Noncopyable.h
+++ b/JavaScriptCore/wtf/Noncopyable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
diff --git a/JavaScriptCore/wtf/NullPtr.h b/JavaScriptCore/wtf/NullPtr.h
new file mode 100644
index 0000000..10a5814
--- /dev/null
+++ b/JavaScriptCore/wtf/NullPtr.h
@@ -0,0 +1,48 @@
+/*
+
+Copyright (C) 2010 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef NullPtr_h
+#define NullPtr_h
+
+// For compilers and standard libraries that do not yet include it, this adds the
+// nullptr_t type and nullptr object. They are defined in the same namespaces they
+// would be in compiler and library that had the support.
+
+#ifndef __has_feature
+ #define __has_feature(feature) 0
+#endif
+
+#if !__has_feature(cxx_nullptr)
+
+namespace std {
+ class nullptr_t { };
+}
+
+extern std::nullptr_t nullptr;
+
+#endif
+
+#endif
diff --git a/JavaScriptCore/wtf/OwnArrayPtr.h b/JavaScriptCore/wtf/OwnArrayPtr.h
index ce056b3..643b90b 100644
--- a/JavaScriptCore/wtf/OwnArrayPtr.h
+++ b/JavaScriptCore/wtf/OwnArrayPtr.h
@@ -23,6 +23,7 @@
#include "Assertions.h"
#include "Noncopyable.h"
+#include "NullPtr.h"
#include "OwnArrayPtrCommon.h"
#include <algorithm>
@@ -73,6 +74,7 @@ public:
#endif
OwnArrayPtr& operator=(const PassOwnArrayPtr<T>&);
+ OwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> OwnArrayPtr& operator=(const PassOwnArrayPtr<U>&);
void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); }
diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h
index cadfad2..cdc277c 100644
--- a/JavaScriptCore/wtf/OwnPtr.h
+++ b/JavaScriptCore/wtf/OwnPtr.h
@@ -23,6 +23,7 @@
#include "Assertions.h"
#include "Noncopyable.h"
+#include "NullPtr.h"
#include "OwnPtrCommon.h"
#include "TypeTraits.h"
#include <algorithm>
@@ -72,6 +73,7 @@ namespace WTF {
operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
OwnPtr& operator=(const PassOwnPtr<T>&);
+ OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
diff --git a/JavaScriptCore/wtf/PassOwnArrayPtr.h b/JavaScriptCore/wtf/PassOwnArrayPtr.h
index 597339c..6a55491 100644
--- a/JavaScriptCore/wtf/PassOwnArrayPtr.h
+++ b/JavaScriptCore/wtf/PassOwnArrayPtr.h
@@ -27,6 +27,7 @@
#define WTF_PassOwnArrayPtr_h
#include "Assertions.h"
+#include "NullPtr.h"
#include "OwnArrayPtrCommon.h"
#include "TypeTraits.h"
@@ -72,6 +73,7 @@ public:
#endif
PassOwnArrayPtr& operator=(const PassOwnArrayPtr<T>&);
+ PassOwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> PassOwnArrayPtr& operator=(const PassOwnArrayPtr<U>&);
template<typename U> friend PassOwnArrayPtr<U> adoptArrayPtr(U*);
diff --git a/JavaScriptCore/wtf/PassOwnPtr.h b/JavaScriptCore/wtf/PassOwnPtr.h
index a223fa9..60453fc 100644
--- a/JavaScriptCore/wtf/PassOwnPtr.h
+++ b/JavaScriptCore/wtf/PassOwnPtr.h
@@ -27,6 +27,7 @@
#define WTF_PassOwnPtr_h
#include "Assertions.h"
+#include "NullPtr.h"
#include "OwnPtrCommon.h"
#include "TypeTraits.h"
@@ -71,6 +72,7 @@ namespace WTF {
operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; }
PassOwnPtr& operator=(const PassOwnPtr<T>&);
+ PassOwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&);
template<typename U> friend PassOwnPtr<U> adoptPtr(U*);
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h
index 052d6e2..b179cef 100644
--- a/JavaScriptCore/wtf/PassRefPtr.h
+++ b/JavaScriptCore/wtf/PassRefPtr.h
@@ -22,6 +22,7 @@
#define WTF_PassRefPtr_h
#include "AlwaysInline.h"
+#include "NullPtr.h"
namespace WTF {
@@ -90,6 +91,7 @@ namespace WTF {
PassRefPtr& operator=(T*);
PassRefPtr& operator=(const PassRefPtr&);
+ PassRefPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
template<typename U> PassRefPtr& operator=(const RefPtr<U>&);
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 1843bea..9895824 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -398,7 +398,7 @@
/* OS(NETBSD) - NetBSD */
#if defined(__NetBSD__)
-#define WTF_PLATFORM_NETBSD 1
+#define WTF_OS_NETBSD 1
#endif
/* OS(OPENBSD) - OpenBSD */
@@ -574,6 +574,8 @@
#define WTF_USE_QT4_UNICODE 1
#elif OS(WINCE)
#define WTF_USE_WINCE_UNICODE 1
+#elif PLATFORM(BREWMP)
+#define WTF_USE_BREWMP_UNICODE 1
#elif PLATFORM(GTK)
/* The GTK+ Unicode backend is configurable */
#else
@@ -692,6 +694,10 @@
#define USE_SYSTEM_MALLOC 1
#endif
+#if PLATFORM(BREWMP_SIMULATOR)
+#define ENABLE_JIT 0
+#endif
+
#if !defined(HAVE_ACCESSIBILITY)
#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
#define HAVE_ACCESSIBILITY 1
@@ -934,19 +940,17 @@
#define ENABLE_FULLSCREEN_API 0
#endif
-#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
+#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64)
#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \
|| (CPU(IA64) && !CPU(IA64_32)) \
|| CPU(ALPHA) \
|| CPU(SPARC64) \
|| CPU(PPC64)
#define WTF_USE_JSVALUE64 1
-#elif CPU(ARM_TRADITIONAL) && COMPILER(MSVC)
-#define WTF_USE_JSVALUE32 1
#else
#define WTF_USE_JSVALUE32_64 1
#endif
-#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) */
+#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) */
#if !defined(ENABLE_REPAINT_THROTTLING)
#define ENABLE_REPAINT_THROTTLING 0
@@ -986,10 +990,6 @@
#endif
#endif
- #if !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) && CPU(X86) && USE(JSVALUE32)
- #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0
- #endif
-
#ifndef ENABLE_JIT_OPTIMIZE_CALL
#define ENABLE_JIT_OPTIMIZE_CALL 1
#endif
diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp
index b20652b..7a9b6a8 100644
--- a/JavaScriptCore/wtf/RandomNumber.cpp
+++ b/JavaScriptCore/wtf/RandomNumber.cpp
@@ -44,6 +44,8 @@ extern "C" {
#include <AEEAppGen.h>
#include <AEESource.h>
#include <AEEStdLib.h>
+#include <wtf/brew/RefPtrBrew.h>
+#include <wtf/brew/ShellBrew.h>
#endif
namespace WTF {
@@ -97,12 +99,8 @@ double randomNumber()
return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
#elif PLATFORM(BREWMP)
uint32_t bits;
- ISource* randomSource;
-
- IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell;
- ISHELL_CreateInstance(shell, AEECLSID_RANDOM, reinterpret_cast<void**>(&randomSource));
- ISOURCE_Read(randomSource, reinterpret_cast<char*>(&bits), 4);
- ISOURCE_Release(randomSource);
+ PlatformRefPtr<ISource> randomSource = createRefPtrInstance<ISource>(AEECLSID_RANDOM);
+ ISOURCE_Read(randomSource.get(), reinterpret_cast<char*>(&bits), 4);
return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
#else
diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h
index ae414c0..1f1c00e 100644
--- a/JavaScriptCore/wtf/RandomNumberSeed.h
+++ b/JavaScriptCore/wtf/RandomNumberSeed.h
@@ -64,6 +64,8 @@ inline void initializeRandomNumberGenerator()
init_by_array(initializationBuffer, 4);
#elif COMPILER(MSVC) && defined(_CRT_RAND_S)
// On Windows we use rand_s which initialises itself
+#elif PLATFORM(BREWMP)
+ // On Brew MP we use AEECLSID_RANDOM which initialises itself
#elif OS(UNIX)
// srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved
timeval time;
diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h
index 8bd1ac3..6afa886 100644
--- a/JavaScriptCore/wtf/RefPtr.h
+++ b/JavaScriptCore/wtf/RefPtr.h
@@ -24,7 +24,6 @@
#define WTF_RefPtr_h
#include <algorithm>
-#include "AlwaysInline.h"
#include "FastAllocBase.h"
#include "PassRefPtr.h"
@@ -75,6 +74,7 @@ namespace WTF {
RefPtr& operator=(T*);
RefPtr& operator=(const PassRefPtr<T>&);
RefPtr& operator=(const NonNullPassRefPtr<T>&);
+ RefPtr& operator=(std::nullptr_t) { clear(); return *this; }
template<typename U> RefPtr& operator=(const RefPtr<U>&);
template<typename U> RefPtr& operator=(const PassRefPtr<U>&);
template<typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&);
diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h
index 68b5a04..8a14cfe 100644
--- a/JavaScriptCore/wtf/RetainPtr.h
+++ b/JavaScriptCore/wtf/RetainPtr.h
@@ -22,6 +22,7 @@
#define RetainPtr_h
#include "HashTraits.h"
+#include "NullPtr.h"
#include "TypeTraits.h"
#include <algorithm>
#include <CoreFoundation/CoreFoundation.h>
@@ -86,6 +87,7 @@ namespace WTF {
template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
RetainPtr& operator=(PtrType);
template<typename U> RetainPtr& operator=(U*);
+ RetainPtr& operator=(std::nullptr_t) { clear(); return *this; }
void adoptCF(PtrType);
void adoptNS(PtrType);
diff --git a/JavaScriptCore/wtf/StringHashFunctions.h b/JavaScriptCore/wtf/StringHasher.h
index 3ad7701..63ce74f 100644
--- a/JavaScriptCore/wtf/StringHashFunctions.h
+++ b/JavaScriptCore/wtf/StringHasher.h
@@ -18,8 +18,8 @@
* Boston, MA 02110-1301, USA.
*
*/
-#ifndef WTF_StringHashFunctions_h
-#define WTF_StringHashFunctions_h
+#ifndef WTF_StringHasher_h
+#define WTF_StringHasher_h
#include <wtf/unicode/Unicode.h>
@@ -167,4 +167,4 @@ private:
} // namespace WTF
-#endif // WTF_StringHashFunctions_h
+#endif // WTF_StringHasher_h
diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h
index 240b497..81b7d0c 100644
--- a/JavaScriptCore/wtf/TCSpinLock.h
+++ b/JavaScriptCore/wtf/TCSpinLock.h
@@ -38,8 +38,6 @@
#include <time.h> /* For nanosleep() */
-#include <sched.h> /* For sched_yield() */
-
#if HAVE(STDINT_H)
#include <stdint.h>
#elif HAVE(INTTYPES_H)
@@ -53,6 +51,8 @@
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
+#else
+#include <sched.h> /* For sched_yield() */
#endif
static void TCMalloc_SlowLock(volatile unsigned int* lockword);
@@ -135,7 +135,12 @@ struct TCMalloc_SpinLock {
#define SPINLOCK_INITIALIZER { 0 }
static void TCMalloc_SlowLock(volatile unsigned int* lockword) {
- sched_yield(); // Yield immediately since fast path failed
+// Yield immediately since fast path failed
+#if OS(WINDOWS)
+ Sleep(0);
+#else
+ sched_yield();
+#endif
while (true) {
int r;
#if COMPILER(GCC)
diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp
index a55019b..afeaa5e 100644
--- a/JavaScriptCore/wtf/TypeTraits.cpp
+++ b/JavaScriptCore/wtf/TypeTraits.cpp
@@ -136,4 +136,7 @@ COMPILE_ASSERT((IsSameType<int, RemovePointer<int>::Type>::value), WTF_Test_Remo
COMPILE_ASSERT((IsSameType<int, RemovePointer<int*>::Type>::value), WTF_Test_RemovePointer_int_pointer);
COMPILE_ASSERT((!IsSameType<int, RemovePointer<int**>::Type>::value), WTF_Test_RemovePointer_int_pointer_pointer);
+COMPILE_ASSERT((IsSameType<int, RemoveReference<int>::Type>::value), WTF_Test_RemoveReference_int);
+COMPILE_ASSERT((IsSameType<int, RemoveReference<int&>::Type>::value), WTF_Test_RemoveReference_int_reference);
+
} // namespace WTF
diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h
index cf9b4af..44103cd 100644
--- a/JavaScriptCore/wtf/TypeTraits.h
+++ b/JavaScriptCore/wtf/TypeTraits.h
@@ -39,6 +39,7 @@ namespace WTF {
// IsSameType<T, U>::value
//
// RemovePointer<T>::Type
+ // RemoveReference<T>::Type
// RemoveConst<T>::Type
// RemoveVolatile<T>::Type
// RemoveConstVolatile<T>::Type
@@ -170,6 +171,14 @@ namespace WTF {
typedef T Type;
};
+ template <typename T> struct RemoveReference {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemoveReference<T&> {
+ typedef T Type;
+ };
+
#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
// GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h
index 7f91e1a..5019c33 100644
--- a/JavaScriptCore/wtf/WTFThreadData.h
+++ b/JavaScriptCore/wtf/WTFThreadData.h
@@ -95,12 +95,6 @@ public:
}
#if USE(JSC)
- void initializeIdentifierTable(JSC::IdentifierTable* identifierTable)
- {
- m_defaultIdentifierTable = identifierTable;
- m_currentIdentifierTable = identifierTable;
- }
-
JSC::IdentifierTable* currentIdentifierTable()
{
return m_currentIdentifierTable;
diff --git a/JavaScriptCore/wtf/brew/RefPtrBrew.h b/JavaScriptCore/wtf/brew/RefPtrBrew.h
new file mode 100644
index 0000000..7fb0b7c
--- /dev/null
+++ b/JavaScriptCore/wtf/brew/RefPtrBrew.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2009 Martin Robinson
+ * Copyright (C) 2010 Company 100, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RefPtrBrew_h
+#define RefPtrBrew_h
+
+#include "AlwaysInline.h"
+#include "PlatformRefPtr.h"
+#include <AEEIBase.h>
+#include <algorithm>
+
+namespace WTF {
+
+// All Brew MP classes are derived from either IBase or IQI.
+// Technically, IBase and IQI are different types. However, it is
+// okay to cast both types to IBase because they have AddRef and Release
+// in the same method vtable slots.
+template <typename T> inline T* refPlatformPtr(T* ptr)
+{
+ if (ptr)
+ IBase_AddRef(reinterpret_cast<IBase*>(ptr));
+ return ptr;
+}
+
+template <typename T> inline void derefPlatformPtr(T* ptr)
+{
+ if (ptr)
+ IBase_Release(reinterpret_cast<IBase*>(ptr));
+}
+
+} // namespace WTF
+
+#endif // RefPtrBrew_h
diff --git a/JavaScriptCore/wtf/brew/ShellBrew.h b/JavaScriptCore/wtf/brew/ShellBrew.h
index 7416eca..faccc75 100644
--- a/JavaScriptCore/wtf/brew/ShellBrew.h
+++ b/JavaScriptCore/wtf/brew/ShellBrew.h
@@ -34,6 +34,7 @@
#include <wtf/Assertions.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/PlatformRefPtr.h>
namespace WTF {
@@ -49,8 +50,21 @@ static inline PassOwnPtr<T> createInstance(AEECLSID cls)
return instance;
}
+template <typename T>
+static inline PlatformRefPtr<T> createRefPtrInstance(AEECLSID cls)
+{
+ T* instance = 0;
+
+ IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell;
+ ISHELL_CreateInstance(shell, cls, reinterpret_cast<void**>(&instance));
+ ASSERT(instance);
+
+ return adoptPlatformRef(instance);
+}
+
} // namespace WTF
using WTF::createInstance;
+using WTF::createRefPtrInstance;
#endif // ShellBrew_h
diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp
index 298bb27..c89c036 100644
--- a/JavaScriptCore/wtf/dtoa.cpp
+++ b/JavaScriptCore/wtf/dtoa.cpp
@@ -1824,8 +1824,8 @@ unsigned numberToString(double d, NumberToStringBuffer buffer)
// Convert to decimal with rounding.
DecimalNumber number(d);
return number.exponent() >= -6 && number.exponent() < 21
- ? number.toStringDecimal(buffer)
- : number.toStringExponential(buffer);
+ ? number.toStringDecimal(buffer, NumberToStringBufferLength)
+ : number.toStringExponential(buffer, NumberToStringBufferLength);
}
} // namespace WTF
diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h
index 7e4fc41..3924a1c 100644
--- a/JavaScriptCore/wtf/dtoa.h
+++ b/JavaScriptCore/wtf/dtoa.h
@@ -39,7 +39,8 @@ void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exp
void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits.
-typedef UChar NumberToStringBuffer[96];
+const unsigned NumberToStringBufferLength = 96;
+typedef UChar NumberToStringBuffer[NumberToStringBufferLength];
unsigned numberToString(double, NumberToStringBuffer);
} // namespace WTF
diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp
index 7d09f12..c048a1b 100644
--- a/JavaScriptCore/wtf/text/CString.cpp
+++ b/JavaScriptCore/wtf/text/CString.cpp
@@ -36,12 +36,12 @@ CString::CString(const char* str)
init(str, strlen(str));
}
-CString::CString(const char* str, unsigned length)
+CString::CString(const char* str, size_t length)
{
init(str, length);
}
-void CString::init(const char* str, unsigned length)
+void CString::init(const char* str, size_t length)
{
if (!str)
return;
diff --git a/JavaScriptCore/wtf/text/CString.h b/JavaScriptCore/wtf/text/CString.h
index d8250c5..343a7a5 100644
--- a/JavaScriptCore/wtf/text/CString.h
+++ b/JavaScriptCore/wtf/text/CString.h
@@ -40,8 +40,8 @@ public:
private:
friend class CString;
- static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); }
- CStringBuffer(unsigned length) : m_vector(length) { }
+ static PassRefPtr<CStringBuffer> create(size_t length) { return adoptRef(new CStringBuffer(length)); }
+ CStringBuffer(size_t length) : m_vector(length) { }
char* mutableData() { return m_vector.data(); }
Vector<char> m_vector;
@@ -53,7 +53,7 @@ class CString {
public:
CString() { }
CString(const char*);
- CString(const char*, unsigned length);
+ CString(const char*, size_t length);
CString(CStringBuffer* buffer) : m_buffer(buffer) { }
static CString newUninitialized(size_t length, char*& characterBuffer);
@@ -62,7 +62,7 @@ public:
return m_buffer ? m_buffer->data() : 0;
}
char* mutableData();
- unsigned length() const
+ size_t length() const
{
return m_buffer ? m_buffer->length() - 1 : 0;
}
@@ -73,7 +73,7 @@ public:
private:
void copyBufferIfNeeded();
- void init(const char*, unsigned length);
+ void init(const char*, size_t length);
RefPtr<CStringBuffer> m_buffer;
};
diff --git a/JavaScriptCore/wtf/text/StringBuffer.h b/JavaScriptCore/wtf/text/StringBuffer.h
index c29dd79..a546bf3 100644
--- a/JavaScriptCore/wtf/text/StringBuffer.h
+++ b/JavaScriptCore/wtf/text/StringBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
#include <wtf/unicode/Unicode.h>
+#include <limits>
namespace WTF {
@@ -39,9 +40,12 @@ class StringBuffer : public Noncopyable {
public:
explicit StringBuffer(unsigned length)
: m_length(length)
- , m_data(static_cast<UChar*>(fastMalloc(length * sizeof(UChar))))
{
+ if (m_length > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+ CRASH();
+ m_data = static_cast<UChar*>(fastMalloc(m_length * sizeof(UChar)));
}
+
~StringBuffer()
{
fastFree(m_data);
@@ -55,8 +59,11 @@ public:
void resize(unsigned newLength)
{
- if (newLength > m_length)
+ if (newLength > m_length) {
+ if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+ CRASH();
m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar)));
+ }
m_length = newLength;
}
@@ -72,8 +79,8 @@ private:
UChar* m_data;
};
-}
+} // namespace WTF
using WTF::StringBuffer;
-#endif
+#endif // StringBuffer_h
diff --git a/JavaScriptCore/wtf/text/StringBuilder.cpp b/JavaScriptCore/wtf/text/StringBuilder.cpp
new file mode 100644
index 0000000..dfc9ff3
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringBuilder.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StringBuilder.h"
+
+#include "WTFString.h"
+
+namespace WTF {
+
+void StringBuilder::reifyString()
+{
+ // Check if the string already exists.
+ if (!m_string.isNull()) {
+ ASSERT(m_string.length() == m_length);
+ return;
+ }
+
+ // Check for empty.
+ if (!m_length) {
+ m_string = StringImpl::empty();
+ return;
+ }
+
+ // Must be valid in the buffer, take a substring (unless string fills the buffer).
+ ASSERT(m_buffer && m_length <= m_buffer->length());
+ m_string = (m_length == m_buffer->length())
+ ? m_buffer.get()
+ : StringImpl::create(m_buffer, 0, m_length);
+}
+
+void StringBuilder::resize(unsigned newSize)
+{
+ // Check newSize < m_length, hence m_length > 0.
+ ASSERT(newSize <= m_length);
+ if (newSize == m_length)
+ return;
+ ASSERT(m_length);
+
+ // If there is a buffer, we only need to duplicate it if it has more than one ref.
+ if (m_buffer) {
+ if (!m_buffer->hasOneRef())
+ allocateBuffer(m_buffer->characters(), m_buffer->length());
+ m_length = newSize;
+ m_string = String();
+ return;
+ }
+
+ // Since m_length && !m_buffer, the string must be valid in m_string, and m_string.length() > 0.
+ ASSERT(!m_string.isEmpty());
+ ASSERT(m_length == m_string.length());
+ ASSERT(newSize < m_string.length());
+ m_length = newSize;
+ m_string = StringImpl::create(m_string.impl(), 0, newSize);
+}
+
+void StringBuilder::reserveCapacity(unsigned newCapacity)
+{
+ if (m_buffer) {
+ // If there is already a buffer, then grow if necessary.
+ if (newCapacity > m_buffer->length())
+ allocateBuffer(m_buffer->characters(), newCapacity);
+ } else {
+ // Grow the string, if necessary.
+ if (newCapacity > m_length)
+ allocateBuffer(m_string.characters(), newCapacity);
+ }
+}
+
+// Allocate a new buffer, copying in currentCharacters (these may come from either m_string
+// or m_buffer, neither will be reassigned until the copy has completed).
+void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requiredLength)
+{
+ // Copy the existing data into a new buffer, set result to point to the end of the existing data.
+ RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters);
+ memcpy(m_bufferCharacters, currentCharacters, static_cast<size_t>(m_length) * sizeof(UChar)); // This can't overflow.
+
+ // Update the builder state.
+ m_buffer = buffer.release();
+ m_string = String();
+}
+
+// Make 'length' additional capacity be available in m_buffer, update m_string & m_length,
+// return a pointer to the newly allocated storage.
+UChar* StringBuilder::appendUninitialized(unsigned length)
+{
+ ASSERT(length);
+
+ // Calcuate the new size of the builder after appending.
+ unsigned requiredLength = length + m_length;
+ if (requiredLength < length)
+ CRASH();
+
+ if (m_buffer) {
+ // If the buffer is valid it must be at least as long as the current builder contents!
+ ASSERT(m_buffer->length() >= m_length);
+
+ // Check if the buffer already has sufficient capacity.
+ if (requiredLength <= m_buffer->length()) {
+ unsigned currentLength = m_length;
+ m_string = String();
+ m_length = requiredLength;
+ return m_bufferCharacters + currentLength;
+ }
+
+ // We need to realloc the buffer.
+ allocateBuffer(m_buffer->characters(), std::max(requiredLength, m_buffer->length() * 2));
+ } else {
+ ASSERT(m_string.length() == m_length);
+ allocateBuffer(m_string.characters(), std::max(requiredLength, requiredLength * 2));
+ }
+
+ UChar* result = m_bufferCharacters + m_length;
+ m_length = requiredLength;
+ return result;
+}
+
+void StringBuilder::append(const UChar* characters, unsigned length)
+{
+ if (!length)
+ return;
+ ASSERT(characters);
+
+ memcpy(appendUninitialized(length), characters, static_cast<size_t>(length) * 2);
+}
+
+void StringBuilder::append(const char* characters, unsigned length)
+{
+ if (!length)
+ return;
+ ASSERT(characters);
+
+ UChar* dest = appendUninitialized(length);
+ const char* end = characters + length;
+ while (characters < end)
+ *(dest++) = *(const unsigned char*)(characters++);
+}
+
+void StringBuilder::shrinkToFit()
+{
+ // If the buffer is at least 80% full, don't bother copying. Need to tune this heuristic!
+ if (m_buffer && m_buffer->length() > (m_length + (m_length >> 2))) {
+ UChar* result;
+ m_string = StringImpl::createUninitialized(m_length, result);
+ memcpy(result, m_buffer->characters(), static_cast<size_t>(m_length) * 2); // This can't overflow.
+ m_buffer = 0;
+ }
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/text/StringBuilder.h b/JavaScriptCore/wtf/text/StringBuilder.h
new file mode 100644
index 0000000..f10af64
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringBuilder.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StringBuilder_h
+#define StringBuilder_h
+
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WTF {
+
+class StringBuilder {
+public:
+ StringBuilder()
+ : m_length(0)
+ {
+ }
+
+ void append(const UChar*, unsigned);
+ void append(const char*, unsigned);
+
+ void append(const String& string)
+ {
+ // If we're appending to an empty string, and there is not buffer
+ // (in case reserveCapacity has been called) then just retain the
+ // string.
+ if (!m_length && !m_buffer) {
+ m_string = string;
+ m_length = string.length();
+ return;
+ }
+ append(string.characters(), string.length());
+ }
+
+ void append(const char* characters)
+ {
+ if (characters)
+ append(characters, strlen(characters));
+ }
+
+ void append(UChar c)
+ {
+ if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
+ m_bufferCharacters[m_length++] = c;
+ else
+ append(&c, 1);
+ }
+
+ void append(char c)
+ {
+ if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
+ m_bufferCharacters[m_length++] = (unsigned char)c;
+ else
+ append(&c, 1);
+ }
+
+ String toString()
+ {
+ if (m_string.isNull()) {
+ shrinkToFit();
+ reifyString();
+ }
+ return m_string;
+ }
+
+ String toStringPreserveCapacity()
+ {
+ if (m_string.isNull())
+ reifyString();
+ return m_string;
+ }
+
+ unsigned length() const
+ {
+ return m_length;
+ }
+
+ bool isEmpty() const { return !length(); }
+
+ void reserveCapacity(unsigned newCapacity);
+
+ void resize(unsigned newSize);
+
+ void shrinkToFit();
+
+ UChar operator[](unsigned i) const
+ {
+ ASSERT(i < m_length);
+ if (!m_string.isNull())
+ return m_string[i];
+ ASSERT(m_buffer);
+ return m_buffer->characters()[i];
+ }
+
+ void clear()
+ {
+ m_length = 0;
+ m_string = String();
+ m_buffer = 0;
+ }
+
+private:
+ void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
+ UChar* appendUninitialized(unsigned length);
+ void reifyString();
+
+ unsigned m_length;
+ String m_string;
+ RefPtr<StringImpl> m_buffer;
+ UChar* m_bufferCharacters;
+};
+
+} // namespace WTF
+
+using WTF::StringBuilder;
+
+#endif // StringBuilder_h
diff --git a/JavaScriptCore/runtime/StringConcatenate.h b/JavaScriptCore/wtf/text/StringConcatenate.h
index 18a52ef..b54a108 100644
--- a/JavaScriptCore/runtime/StringConcatenate.h
+++ b/JavaScriptCore/wtf/text/StringConcatenate.h
@@ -26,15 +26,45 @@
#ifndef StringConcatenate_h
#define StringConcatenate_h
-#include "UString.h"
+#include <wtf/text/WTFString.h>
-namespace JSC {
+namespace WTF {
template<typename StringType>
class StringTypeAdapter {
};
template<>
+class StringTypeAdapter<char> {
+public:
+ StringTypeAdapter<char>(char buffer)
+ : m_buffer(buffer)
+ {
+ }
+
+ unsigned length() { return 1; }
+ void writeTo(UChar* destination) { *destination = m_buffer; }
+
+private:
+ unsigned char m_buffer;
+};
+
+template<>
+class StringTypeAdapter<UChar> {
+public:
+ StringTypeAdapter<UChar>(UChar buffer)
+ : m_buffer(buffer)
+ {
+ }
+
+ unsigned length() { return 1; }
+ void writeTo(UChar* destination) { *destination = m_buffer; }
+
+private:
+ UChar m_buffer;
+};
+
+template<>
class StringTypeAdapter<char*> {
public:
StringTypeAdapter<char*>(char* buffer)
@@ -79,9 +109,9 @@ private:
};
template<>
-class StringTypeAdapter<UString> {
+class StringTypeAdapter<String> {
public:
- StringTypeAdapter<UString>(UString& string)
+ StringTypeAdapter<String>(String& string)
: m_data(string.characters())
, m_length(string.length())
{
@@ -360,8 +390,15 @@ PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
return resultImpl;
}
+// Convenience only.
+template<typename StringType1>
+String makeString(StringType1 string1)
+{
+ return String(string1);
+}
+
template<typename StringType1, typename StringType2>
-UString makeString(StringType1 string1, StringType2 string2)
+String makeString(StringType1 string1, StringType2 string2)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2);
if (!resultImpl)
@@ -370,7 +407,7 @@ UString makeString(StringType1 string1, StringType2 string2)
}
template<typename StringType1, typename StringType2, typename StringType3>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3);
if (!resultImpl)
@@ -379,7 +416,7 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
if (!resultImpl)
@@ -388,7 +425,7 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
if (!resultImpl)
@@ -397,7 +434,7 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
if (!resultImpl)
@@ -406,7 +443,7 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
if (!resultImpl)
@@ -415,7 +452,7 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
{
PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
if (!resultImpl)
@@ -423,6 +460,8 @@ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3
return resultImpl;
}
-} // namespace JSC
+} // namespace WTF
+
+using WTF::makeString;
#endif
diff --git a/JavaScriptCore/wtf/text/StringHash.h b/JavaScriptCore/wtf/text/StringHash.h
index bfd05eb..d7aabdb 100644
--- a/JavaScriptCore/wtf/text/StringHash.h
+++ b/JavaScriptCore/wtf/text/StringHash.h
@@ -26,7 +26,7 @@
#include "WTFString.h"
#include <wtf/Forward.h>
#include <wtf/HashTraits.h>
-#include <wtf/StringHashFunctions.h>
+#include <wtf/StringHasher.h>
#include <wtf/unicode/Unicode.h>
namespace WTF {
@@ -97,99 +97,26 @@ namespace WTF {
class CaseFoldingHash {
public:
- // Paul Hsieh's SuperFastHash
- // http://www.azillionmonkeys.com/qed/hash.html
+ template<typename T> static inline UChar foldCase(T ch)
+ {
+ return WTF::Unicode::foldCase(ch);
+ }
+
static unsigned hash(const UChar* data, unsigned length)
{
- unsigned l = length;
- const UChar* s = data;
- uint32_t hash = WTF::stringHashingStartValue;
- uint32_t tmp;
-
- int rem = l & 1;
- l >>= 1;
-
- // Main loop.
- for (; l > 0; l--) {
- hash += WTF::Unicode::foldCase(s[0]);
- tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- s += 2;
- hash += hash >> 11;
- }
-
- // Handle end case.
- if (rem) {
- hash += WTF::Unicode::foldCase(s[0]);
- hash ^= hash << 11;
- hash += hash >> 17;
- }
-
- // Force "avalanching" of final 127 bits.
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // 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.
- hash |= !hash << 31;
-
- return hash;
+ return StringHasher::createHash<UChar, foldCase<UChar> >(data, length);
}
static unsigned hash(StringImpl* str)
{
return hash(str->characters(), str->length());
}
-
- static unsigned hash(const char* str, unsigned length)
- {
- // This hash is designed to work on 16-bit chunks at a time. But since the normal case
- // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
- // were 16-bit chunks, which will give matching results.
- unsigned l = length;
- const char* s = str;
- uint32_t hash = WTF::stringHashingStartValue;
- uint32_t tmp;
-
- int rem = l & 1;
- l >>= 1;
-
- // Main loop
- for (; l > 0; l--) {
- hash += WTF::Unicode::foldCase(s[0]);
- tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- s += 2;
- hash += hash >> 11;
- }
-
- // Handle end case
- if (rem) {
- hash += WTF::Unicode::foldCase(s[0]);
- hash ^= hash << 11;
- hash += hash >> 17;
- }
-
- // Force "avalanching" of final 127 bits
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // 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
- hash |= !hash << 31;
-
- return hash;
+ static unsigned hash(const char* data, unsigned length)
+ {
+ return StringHasher::createHash<char, foldCase<char> >(data, length);
}
-
+
static bool equal(const StringImpl* a, const StringImpl* b)
{
if (a == b)
diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp
index 7822c00..e1e08ee 100644
--- a/JavaScriptCore/wtf/text/StringImpl.cpp
+++ b/JavaScriptCore/wtf/text/StringImpl.cpp
@@ -81,7 +81,7 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*&
// Allocate a single buffer large enough to contain the StringImpl
// struct as well as the data which it contains. This removes one
// heap allocation from this call.
- if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar)))
+ if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)))
CRASH();
size_t size = sizeof(StringImpl) + length * sizeof(UChar);
StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h
index 7025d9f..897751d 100644
--- a/JavaScriptCore/wtf/text/StringImpl.h
+++ b/JavaScriptCore/wtf/text/StringImpl.h
@@ -29,7 +29,7 @@
#include <wtf/Forward.h>
#include <wtf/OwnFastMallocPtr.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/StringHashFunctions.h>
+#include <wtf/StringHasher.h>
#include <wtf/Vector.h>
#include <wtf/text/StringImplBase.h>
#include <wtf/unicode/Unicode.h>
@@ -165,7 +165,7 @@ public:
return empty();
}
- if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar))) {
+ if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) {
output = 0;
return 0;
}
@@ -187,6 +187,8 @@ public:
{
if (size_t size = vector.size()) {
ASSERT(vector.data());
+ if (size > std::numeric_limits<unsigned>::max())
+ CRASH();
return adoptRef(new StringImpl(vector.releaseBuffer(), size));
}
return empty();
diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp
index 9b53e81..5161477 100644
--- a/JavaScriptCore/wtf/text/WTFString.cpp
+++ b/JavaScriptCore/wtf/text/WTFString.cpp
@@ -48,9 +48,12 @@ String::String(const UChar* str)
if (!str)
return;
- int len = 0;
+ size_t len = 0;
while (str[len] != UChar(0))
len++;
+
+ if (len > std::numeric_limits<unsigned>::max())
+ CRASH();
m_impl = StringImpl::create(str, len);
}
@@ -175,6 +178,8 @@ void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
ASSERT(charactersToAppend);
UChar* data;
+ if (lengthToAppend > std::numeric_limits<unsigned>::max() - length())
+ CRASH();
RefPtr<StringImpl> newImpl =
StringImpl::createUninitialized(length() + lengthToAppend, data);
memcpy(data, characters(), length() * sizeof(UChar));
@@ -196,6 +201,8 @@ void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un
ASSERT(charactersToInsert);
UChar* data;
+ if (lengthToInsert > std::numeric_limits<unsigned>::max() - length())
+ CRASH();
RefPtr<StringImpl> newImpl =
StringImpl::createUninitialized(length() + lengthToInsert, data);
memcpy(data, characters(), position * sizeof(UChar));
@@ -718,6 +725,9 @@ CString String::utf8(bool strict) const
String String::fromUTF8(const char* stringStart, size_t length)
{
+ if (length > std::numeric_limits<unsigned>::max())
+ CRASH();
+
if (!stringStart)
return String();
diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h
index c755c6c..50524b1 100644
--- a/JavaScriptCore/wtf/unicode/Unicode.h
+++ b/JavaScriptCore/wtf/unicode/Unicode.h
@@ -33,6 +33,8 @@
#include <wtf/unicode/glib/UnicodeGLib.h>
#elif USE(WINCE_UNICODE)
#include <wtf/unicode/wince/UnicodeWinCE.h>
+#elif USE(BREWMP_UNICODE)
+#include <wtf/unicode/brew/UnicodeBrew.h>
#else
#error "Unknown Unicode implementation"
#endif
diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp
new file mode 100644
index 0000000..8367f17
--- /dev/null
+++ b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2006 George Staikos <staikos@kde.org>
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 Company 100, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "UnicodeBrew.h"
+
+#include <wchar.h>
+#include <wctype.h>
+
+namespace WTF {
+namespace Unicode {
+
+UChar toLower(UChar c)
+{
+ return towlower(c);
+}
+
+UChar toUpper(UChar c)
+{
+ return towupper(c);
+}
+
+UChar foldCase(UChar c)
+{
+ return towlower(c);
+}
+
+bool isPrintableChar(UChar c)
+{
+ return !!iswprint(c);
+}
+
+bool isUpper(UChar c)
+{
+ return !!iswupper(c);
+}
+
+bool isLower(UChar c)
+{
+ return !!iswlower(c);
+}
+
+bool isDigit(UChar c)
+{
+ return !!iswdigit(c);
+}
+
+bool isPunct(UChar c)
+{
+ return !!iswpunct(c);
+}
+
+bool isAlphanumeric(UChar c)
+{
+ return !!iswalnum(c);
+}
+
+int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
+{
+ const UChar* sourceIterator = source;
+ const UChar* sourceEnd = source + sourceLength;
+ UChar* resultIterator = result;
+ UChar* resultEnd = result + resultLength;
+
+ if (sourceLength <= resultLength) {
+ while (sourceIterator < sourceEnd)
+ *resultIterator++ = towlower(*sourceIterator++);
+ } else {
+ while (resultIterator < resultEnd)
+ *resultIterator++ = towlower(*sourceIterator++);
+ }
+
+ int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0;
+ *isError = !!remainingCharacters;
+ if (resultIterator < resultEnd)
+ *resultIterator = 0;
+
+ return (resultIterator - result) + remainingCharacters;
+}
+
+int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
+{
+ const UChar* sourceIterator = source;
+ const UChar* sourceEnd = source + sourceLength;
+ UChar* resultIterator = result;
+ UChar* resultEnd = result + resultLength;
+
+ if (sourceLength <= resultLength) {
+ while (sourceIterator < sourceEnd)
+ *resultIterator++ = towupper(*sourceIterator++);
+ } else {
+ while (resultIterator < resultEnd)
+ *resultIterator++ = towupper(*sourceIterator++);
+ }
+
+ int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0;
+ *isError = !!remainingCharacters;
+ if (resultIterator < resultEnd)
+ *resultIterator = 0;
+
+ return (resultIterator - result) + remainingCharacters;
+}
+
+int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
+{
+ *isError = false;
+ if (resultLength < sourceLength) {
+ *isError = true;
+ return sourceLength;
+ }
+ for (int i = 0; i < sourceLength; ++i)
+ result[i] = foldCase(source[i]);
+ return sourceLength;
+}
+
+UChar toTitleCase(UChar c)
+{
+ return towupper(c);
+}
+
+Direction direction(UChar32 c)
+{
+ return static_cast<Direction>(ICU::direction(c));
+}
+
+CharCategory category(unsigned int c)
+{
+ return static_cast<CharCategory>(TO_MASK((int8_t) ICU::category(c)));
+}
+
+DecompositionType decompositionType(UChar32 c)
+{
+ return static_cast<DecompositionType>(ICU::decompositionType(c));
+}
+
+unsigned char combiningClass(UChar32 c)
+{
+ return ICU::combiningClass(c);
+}
+
+UChar mirroredChar(UChar32 c)
+{
+ return ICU::mirroredChar(c);
+}
+
+int digitValue(UChar c)
+{
+ return ICU::digitValue(c);
+}
+
+bool isSpace(UChar c)
+{
+ return !!iswspace(c);
+}
+
+bool isLetter(UChar c)
+{
+ return !!iswalpha(c);
+}
+
+} // namespace Unicode
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h
new file mode 100644
index 0000000..1d7576f
--- /dev/null
+++ b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2006 George Staikos <staikos@kde.org>
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 Company 100, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeBrew_h
+#define UnicodeBrew_h
+
+#include "UnicodeFromICU.h"
+#include "UnicodeMacrosFromICU.h"
+
+namespace WTF {
+namespace Unicode {
+
+enum Direction {
+ LeftToRight = ICU::U_LEFT_TO_RIGHT,
+ RightToLeft = ICU::U_RIGHT_TO_LEFT,
+ EuropeanNumber = ICU::U_EUROPEAN_NUMBER,
+ EuropeanNumberSeparator = ICU::U_EUROPEAN_NUMBER_SEPARATOR,
+ EuropeanNumberTerminator = ICU::U_EUROPEAN_NUMBER_TERMINATOR,
+ ArabicNumber = ICU::U_ARABIC_NUMBER,
+ CommonNumberSeparator = ICU::U_COMMON_NUMBER_SEPARATOR,
+ BlockSeparator = ICU::U_BLOCK_SEPARATOR,
+ SegmentSeparator = ICU::U_SEGMENT_SEPARATOR,
+ WhiteSpaceNeutral = ICU::U_WHITE_SPACE_NEUTRAL,
+ OtherNeutral = ICU::U_OTHER_NEUTRAL,
+ LeftToRightEmbedding = ICU::U_LEFT_TO_RIGHT_EMBEDDING,
+ LeftToRightOverride = ICU::U_LEFT_TO_RIGHT_OVERRIDE,
+ RightToLeftArabic = ICU::U_RIGHT_TO_LEFT_ARABIC,
+ RightToLeftEmbedding = ICU::U_RIGHT_TO_LEFT_EMBEDDING,
+ RightToLeftOverride = ICU::U_RIGHT_TO_LEFT_OVERRIDE,
+ PopDirectionalFormat = ICU::U_POP_DIRECTIONAL_FORMAT,
+ NonSpacingMark = ICU::U_DIR_NON_SPACING_MARK,
+ BoundaryNeutral = ICU::U_BOUNDARY_NEUTRAL
+};
+
+enum DecompositionType {
+ DecompositionNone = ICU::U_DT_NONE,
+ DecompositionCanonical = ICU::U_DT_CANONICAL,
+ DecompositionCompat = ICU::U_DT_COMPAT,
+ DecompositionCircle = ICU::U_DT_CIRCLE,
+ DecompositionFinal = ICU::U_DT_FINAL,
+ DecompositionFont = ICU::U_DT_FONT,
+ DecompositionFraction = ICU::U_DT_FRACTION,
+ DecompositionInitial = ICU::U_DT_INITIAL,
+ DecompositionIsolated = ICU::U_DT_ISOLATED,
+ DecompositionMedial = ICU::U_DT_MEDIAL,
+ DecompositionNarrow = ICU::U_DT_NARROW,
+ DecompositionNoBreak = ICU::U_DT_NOBREAK,
+ DecompositionSmall = ICU::U_DT_SMALL,
+ DecompositionSquare = ICU::U_DT_SQUARE,
+ DecompositionSub = ICU::U_DT_SUB,
+ DecompositionSuper = ICU::U_DT_SUPER,
+ DecompositionVertical = ICU::U_DT_VERTICAL,
+ DecompositionWide = ICU::U_DT_WIDE,
+};
+
+enum CharCategory {
+ NoCategory = 0,
+ Other_NotAssigned = TO_MASK(ICU::U_GENERAL_OTHER_TYPES),
+ Letter_Uppercase = TO_MASK(ICU::U_UPPERCASE_LETTER),
+ Letter_Lowercase = TO_MASK(ICU::U_LOWERCASE_LETTER),
+ Letter_Titlecase = TO_MASK(ICU::U_TITLECASE_LETTER),
+ Letter_Modifier = TO_MASK(ICU::U_MODIFIER_LETTER),
+ Letter_Other = TO_MASK(ICU::U_OTHER_LETTER),
+
+ Mark_NonSpacing = TO_MASK(ICU::U_NON_SPACING_MARK),
+ Mark_Enclosing = TO_MASK(ICU::U_ENCLOSING_MARK),
+ Mark_SpacingCombining = TO_MASK(ICU::U_COMBINING_SPACING_MARK),
+
+ Number_DecimalDigit = TO_MASK(ICU::U_DECIMAL_DIGIT_NUMBER),
+ Number_Letter = TO_MASK(ICU::U_LETTER_NUMBER),
+ Number_Other = TO_MASK(ICU::U_OTHER_NUMBER),
+
+ Separator_Space = TO_MASK(ICU::U_SPACE_SEPARATOR),
+ Separator_Line = TO_MASK(ICU::U_LINE_SEPARATOR),
+ Separator_Paragraph = TO_MASK(ICU::U_PARAGRAPH_SEPARATOR),
+
+ Other_Control = TO_MASK(ICU::U_CONTROL_CHAR),
+ Other_Format = TO_MASK(ICU::U_FORMAT_CHAR),
+ Other_PrivateUse = TO_MASK(ICU::U_PRIVATE_USE_CHAR),
+ Other_Surrogate = TO_MASK(ICU::U_SURROGATE),
+
+ Punctuation_Dash = TO_MASK(ICU::U_DASH_PUNCTUATION),
+ Punctuation_Open = TO_MASK(ICU::U_START_PUNCTUATION),
+ Punctuation_Close = TO_MASK(ICU::U_END_PUNCTUATION),
+ Punctuation_Connector = TO_MASK(ICU::U_CONNECTOR_PUNCTUATION),
+ Punctuation_Other = TO_MASK(ICU::U_OTHER_PUNCTUATION),
+
+ Symbol_Math = TO_MASK(ICU::U_MATH_SYMBOL),
+ Symbol_Currency = TO_MASK(ICU::U_CURRENCY_SYMBOL),
+ Symbol_Modifier = TO_MASK(ICU::U_MODIFIER_SYMBOL),
+ Symbol_Other = TO_MASK(ICU::U_OTHER_SYMBOL),
+
+ Punctuation_InitialQuote = TO_MASK(ICU::U_INITIAL_PUNCTUATION),
+ Punctuation_FinalQuote = TO_MASK(ICU::U_FINAL_PUNCTUATION)
+};
+
+UChar foldCase(UChar);
+
+int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+
+int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+
+UChar toUpper(UChar);
+UChar toLower(UChar);
+
+bool isUpper(UChar);
+
+int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+
+UChar toTitleCase(UChar);
+
+inline bool isArabicChar(UChar32 c)
+{
+ return c >= 0x0600 && c <= 0x06FF;
+}
+
+bool isAlphanumeric(UChar);
+
+CharCategory category(unsigned int);
+
+inline bool isSeparatorSpace(UChar c)
+{
+ return category(c) == Separator_Space;
+}
+
+bool isPrintableChar(UChar);
+
+bool isDigit(UChar);
+
+bool isPunct(UChar);
+
+inline bool hasLineBreakingPropertyComplexContext(UChar32)
+{
+ // FIXME: implement!
+ return false;
+}
+
+inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c)
+{
+ // FIXME
+ return false;
+}
+
+UChar mirroredChar(UChar32);
+
+Direction direction(UChar32);
+
+bool isLower(UChar);
+
+int digitValue(UChar);
+
+unsigned char combiningClass(UChar32);
+
+DecompositionType decompositionType(UChar32);
+
+inline int umemcasecmp(const UChar* a, const UChar* b, int len)
+{
+ for (int i = 0; i < len; ++i) {
+ UChar c1 = foldCase(a[i]);
+ UChar c2 = foldCase(b[i]);
+ if (c1 != c2)
+ return c1 - c2;
+ }
+ return 0;
+}
+
+bool isSpace(UChar);
+bool isLetter(UChar);
+
+} // namespace Unicode
+} // namespace WTF
+
+#endif
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index 547ed32..eaa7a07 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -31,6 +31,9 @@
#include <config.h>
#include <stdint.h>
+#if USE(QT_ICU_TEXT_BREAKING)
+#include <unicode/ubrk.h>
+#endif
QT_BEGIN_NAMESPACE
namespace QUnicodeTables {
@@ -63,7 +66,10 @@ typedef wchar_t UChar;
#else
typedef uint16_t UChar;
#endif
+
+#if !USE(QT_ICU_TEXT_BREAKING)
typedef uint32_t UChar32;
+#endif
namespace WTF {
namespace Unicode {
@@ -150,7 +156,7 @@ enum CharCategory {
inline UChar32 toLower(UChar32 ch)
{
- return QChar::toLower(ch);
+ return QChar::toLower(uint32_t(ch));
}
inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
@@ -206,9 +212,9 @@ inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLen
return rindex + needed;
}
-inline UChar32 toUpper(UChar32 ch)
+inline UChar32 toUpper(UChar32 c)
{
- return QChar::toUpper(ch);
+ return QChar::toUpper(uint32_t(c));
}
inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
@@ -266,12 +272,12 @@ inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLen
inline int toTitleCase(UChar32 c)
{
- return QChar::toTitleCase(c);
+ return QChar::toTitleCase(uint32_t(c));
}
inline UChar32 foldCase(UChar32 c)
{
- return QChar::toCaseFolded(c);
+ return QChar::toCaseFolded(uint32_t(c));
}
inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
@@ -296,12 +302,12 @@ inline bool isPrintableChar(UChar32 c)
{
const uint test = U_MASK(QChar::Other_Control) |
U_MASK(QChar::Other_NotAssigned);
- return !(U_MASK(QChar::category(c)) & test);
+ return !(U_MASK(QChar::category(uint32_t(c))) & test);
}
inline bool isSeparatorSpace(UChar32 c)
{
- return QChar::category(c) == QChar::Separator_Space;
+ return QChar::category(uint32_t(c)) == QChar::Separator_Space;
}
inline bool isPunct(UChar32 c)
@@ -313,12 +319,12 @@ inline bool isPunct(UChar32 c)
U_MASK(QChar::Punctuation_InitialQuote) |
U_MASK(QChar::Punctuation_FinalQuote) |
U_MASK(QChar::Punctuation_Other);
- return U_MASK(QChar::category(c)) & test;
+ return U_MASK(QChar::category(uint32_t(c))) & test;
}
inline bool isLower(UChar32 c)
{
- return QChar::category(c) == QChar::Letter_Lowercase;
+ return QChar::category(uint32_t(c)) == QChar::Letter_Lowercase;
}
inline bool hasLineBreakingPropertyComplexContext(UChar32)
@@ -329,12 +335,12 @@ inline bool hasLineBreakingPropertyComplexContext(UChar32)
inline UChar32 mirroredChar(UChar32 c)
{
- return QChar::mirroredChar(c);
+ return QChar::mirroredChar(uint32_t(c));
}
inline uint8_t combiningClass(UChar32 c)
{
- return QChar::combiningClass(c);
+ return QChar::combiningClass(uint32_t(c));
}
inline DecompositionType decompositionType(UChar32 c)
@@ -356,12 +362,12 @@ inline int umemcasecmp(const UChar* a, const UChar* b, int len)
inline Direction direction(UChar32 c)
{
- return (Direction)QChar::direction(c);
+ return (Direction)QChar::direction(uint32_t(c));
}
inline CharCategory category(UChar32 c)
{
- return (CharCategory) U_MASK(QChar::category(c));
+ return (CharCategory) U_MASK(QChar::category(uint32_t(c)));
}
} }
diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp
index b52b05c..96dac7d 100644
--- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp
+++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp
@@ -27,62 +27,62 @@
namespace WTF {
namespace Unicode {
-wchar_t toLower(wchar_t c)
+UChar toLower(UChar c)
{
return towlower(c);
}
-wchar_t toUpper(wchar_t c)
+UChar toUpper(UChar c)
{
return towupper(c);
}
-wchar_t foldCase(wchar_t c)
+UChar foldCase(UChar c)
{
return towlower(c);
}
-bool isPrintableChar(wchar_t c)
+bool isPrintableChar(UChar c)
{
return !!iswprint(c);
}
-bool isSpace(wchar_t c)
+bool isSpace(UChar c)
{
return !!iswspace(c);
}
-bool isLetter(wchar_t c)
+bool isLetter(UChar c)
{
return !!iswalpha(c);
}
-bool isUpper(wchar_t c)
+bool isUpper(UChar c)
{
return !!iswupper(c);
}
-bool isLower(wchar_t c)
+bool isLower(UChar c)
{
return !!iswlower(c);
}
-bool isDigit(wchar_t c)
+bool isDigit(UChar c)
{
return !!iswdigit(c);
}
-bool isPunct(wchar_t c)
+bool isPunct(UChar c)
{
return !!iswpunct(c);
}
-bool isAlphanumeric(wchar_t c)
+bool isAlphanumeric(UChar c)
{
return !!iswalnum(c);
}
-int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError)
+int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
{
const UChar* sourceIterator = source;
const UChar* sourceEnd = source + sourceLength;
@@ -99,14 +99,14 @@ int toLower(wchar_t* result, int resultLength, const wchar_t* source, int source
if (sourceIterator < sourceEnd)
remainingCharacters += sourceEnd - sourceIterator;
- *isError = (remainingCharacters != 0);
+ *isError = !!remainingCharacters;
if (resultIterator < resultEnd)
*resultIterator = 0;
return (resultIterator - result) + remainingCharacters;
}
-int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError)
+int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
{
const UChar* sourceIterator = source;
const UChar* sourceEnd = source + sourceLength;
@@ -123,14 +123,14 @@ int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int source
if (sourceIterator < sourceEnd)
remainingCharacters += sourceEnd - sourceIterator;
- *isError = (remainingCharacters != 0);
+ *isError = !!remainingCharacters;
if (resultIterator < resultEnd)
*resultIterator = 0;
return (resultIterator - result) + remainingCharacters;
}
-int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError)
+int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError)
{
*isError = false;
if (resultLength < sourceLength) {
@@ -142,7 +142,7 @@ int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourc
return sourceLength;
}
-wchar_t toTitleCase(wchar_t c)
+UChar toTitleCase(UChar c)
{
return towupper(c);
}
@@ -167,12 +167,12 @@ unsigned char combiningClass(UChar32 c)
return UnicodeCE::combiningClass(c);
}
-wchar_t mirroredChar(UChar32 c)
+UChar mirroredChar(UChar32 c)
{
return UnicodeCE::mirroredChar(c);
}
-int digitValue(wchar_t c)
+int digitValue(UChar c)
{
return UnicodeCE::digitValue(c);
}
diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
index 8cc9580..2688aa9 100644
--- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
+++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h
@@ -31,149 +31,147 @@
#define TO_MASK(x) (1 << (x))
namespace WTF {
-
- namespace Unicode {
-
- enum Direction {
- LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT,
- RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT,
- EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER,
- EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR,
- EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR,
- ArabicNumber = UnicodeCE::U_ARABIC_NUMBER,
- CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR,
- BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR,
- SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR,
- WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL,
- OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL,
- LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING,
- LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE,
- RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC,
- RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING,
- RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE,
- PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT,
- NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK,
- BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL
- };
-
- enum DecompositionType {
- DecompositionNone = UnicodeCE::U_DT_NONE,
- DecompositionCanonical = UnicodeCE::U_DT_CANONICAL,
- DecompositionCompat = UnicodeCE::U_DT_COMPAT,
- DecompositionCircle = UnicodeCE::U_DT_CIRCLE,
- DecompositionFinal = UnicodeCE::U_DT_FINAL,
- DecompositionFont = UnicodeCE::U_DT_FONT,
- DecompositionFraction = UnicodeCE::U_DT_FRACTION,
- DecompositionInitial = UnicodeCE::U_DT_INITIAL,
- DecompositionIsolated = UnicodeCE::U_DT_ISOLATED,
- DecompositionMedial = UnicodeCE::U_DT_MEDIAL,
- DecompositionNarrow = UnicodeCE::U_DT_NARROW,
- DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK,
- DecompositionSmall = UnicodeCE::U_DT_SMALL,
- DecompositionSquare = UnicodeCE::U_DT_SQUARE,
- DecompositionSub = UnicodeCE::U_DT_SUB,
- DecompositionSuper = UnicodeCE::U_DT_SUPER,
- DecompositionVertical = UnicodeCE::U_DT_VERTICAL,
- DecompositionWide = UnicodeCE::U_DT_WIDE,
- };
-
- enum CharCategory {
- NoCategory = 0,
- Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES),
- Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER),
- Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER),
- Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER),
- Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER),
- Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER),
-
- Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK),
- Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK),
- Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK),
-
- Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER),
- Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER),
- Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER),
-
- Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR),
- Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR),
- Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR),
-
- Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR),
- Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR),
- Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR),
- Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE),
-
- Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION),
- Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION),
- Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION),
- Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION),
- Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION),
-
- Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL),
- Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL),
- Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL),
- Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL),
-
- Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION),
- Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION)
- };
-
- CharCategory category(unsigned int);
-
- bool isSpace(wchar_t);
- bool isLetter(wchar_t);
- bool isPrintableChar(wchar_t);
- bool isUpper(wchar_t);
- bool isLower(wchar_t);
- bool isPunct(wchar_t);
- bool isDigit(wchar_t);
- bool isAlphanumeric(wchar_t);
- inline bool isSeparatorSpace(wchar_t c) { return category(c) == Separator_Space; }
- inline bool isHighSurrogate(wchar_t c) { return (c & 0xfc00) == 0xd800; }
- inline bool isLowSurrogate(wchar_t c) { return (c & 0xfc00) == 0xdc00; }
-
- wchar_t toLower(wchar_t);
- wchar_t toUpper(wchar_t);
- wchar_t foldCase(wchar_t);
- wchar_t toTitleCase(wchar_t);
- int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError);
- int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError);
- int foldCase(UChar* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError);
-
- int digitValue(wchar_t);
-
- wchar_t mirroredChar(UChar32);
- unsigned char combiningClass(UChar32);
- DecompositionType decompositionType(UChar32);
- Direction direction(UChar32);
- inline bool isArabicChar(UChar32 c)
- {
- return c >= 0x0600 && c <= 0x06FF;
- }
-
- inline bool hasLineBreakingPropertyComplexContext(UChar32)
- {
- return false; // FIXME: implement!
- }
-
- inline int umemcasecmp(const wchar_t* a, const wchar_t* b, int len)
- {
- for (int i = 0; i < len; ++i) {
- wchar_t c1 = foldCase(a[i]);
- wchar_t c2 = foldCase(b[i]);
- if (c1 != c2)
- return c1 - c2;
- }
- return 0;
- }
-
- inline UChar32 surrogateToUcs4(wchar_t high, wchar_t low)
- {
- return (UChar32(high) << 10) + low - 0x35fdc00;
- }
-
- } // namespace Unicode
-
-} // namespace WTF
+namespace Unicode {
+
+enum Direction {
+ LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT,
+ RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT,
+ EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER,
+ EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR,
+ EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR,
+ ArabicNumber = UnicodeCE::U_ARABIC_NUMBER,
+ CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR,
+ BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR,
+ SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR,
+ WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL,
+ OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL,
+ LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING,
+ LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE,
+ RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC,
+ RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING,
+ RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE,
+ PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT,
+ NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK,
+ BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL
+};
+
+enum DecompositionType {
+ DecompositionNone = UnicodeCE::U_DT_NONE,
+ DecompositionCanonical = UnicodeCE::U_DT_CANONICAL,
+ DecompositionCompat = UnicodeCE::U_DT_COMPAT,
+ DecompositionCircle = UnicodeCE::U_DT_CIRCLE,
+ DecompositionFinal = UnicodeCE::U_DT_FINAL,
+ DecompositionFont = UnicodeCE::U_DT_FONT,
+ DecompositionFraction = UnicodeCE::U_DT_FRACTION,
+ DecompositionInitial = UnicodeCE::U_DT_INITIAL,
+ DecompositionIsolated = UnicodeCE::U_DT_ISOLATED,
+ DecompositionMedial = UnicodeCE::U_DT_MEDIAL,
+ DecompositionNarrow = UnicodeCE::U_DT_NARROW,
+ DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK,
+ DecompositionSmall = UnicodeCE::U_DT_SMALL,
+ DecompositionSquare = UnicodeCE::U_DT_SQUARE,
+ DecompositionSub = UnicodeCE::U_DT_SUB,
+ DecompositionSuper = UnicodeCE::U_DT_SUPER,
+ DecompositionVertical = UnicodeCE::U_DT_VERTICAL,
+ DecompositionWide = UnicodeCE::U_DT_WIDE
+};
+
+enum CharCategory {
+ NoCategory = 0,
+ Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES),
+ Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER),
+ Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER),
+ Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER),
+ Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER),
+ Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER),
+
+ Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK),
+ Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK),
+ Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK),
+
+ Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER),
+ Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER),
+ Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER),
+
+ Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR),
+ Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR),
+ Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR),
+
+ Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR),
+ Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR),
+ Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR),
+ Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE),
+
+ Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION),
+ Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION),
+ Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION),
+ Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION),
+ Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION),
+
+ Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL),
+ Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL),
+ Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL),
+ Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL),
+
+ Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION),
+ Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION)
+};
+
+CharCategory category(unsigned int);
+
+bool isSpace(UChar);
+bool isLetter(UChar);
+bool isPrintableChar(UChar);
+bool isUpper(UChar);
+bool isLower(UChar);
+bool isPunct(UChar);
+bool isDigit(UChar);
+bool isAlphanumeric(UChar);
+inline bool isSeparatorSpace(UChar c) { return category(c) == Separator_Space; }
+inline bool isHighSurrogate(UChar c) { return (c & 0xfc00) == 0xd800; }
+inline bool isLowSurrogate(UChar c) { return (c & 0xfc00) == 0xdc00; }
+
+UChar toLower(UChar);
+UChar toUpper(UChar);
+UChar foldCase(UChar);
+UChar toTitleCase(UChar);
+int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError);
+
+int digitValue(UChar);
+
+UChar mirroredChar(UChar32);
+unsigned char combiningClass(UChar32);
+DecompositionType decompositionType(UChar32);
+Direction direction(UChar32);
+inline bool isArabicChar(UChar32 c)
+{
+ return c >= 0x0600 && c <= 0x06FF;
+}
+
+inline bool hasLineBreakingPropertyComplexContext(UChar32)
+{
+ return false; // FIXME: implement!
+}
+
+inline int umemcasecmp(const UChar* a, const UChar* b, int len)
+{
+ for (int i = 0; i < len; ++i) {
+ UChar c1 = foldCase(a[i]);
+ UChar c2 = foldCase(b[i]);
+ if (c1 != c2)
+ return c1 - c2;
+ }
+ return 0;
+}
+
+inline UChar32 surrogateToUcs4(UChar high, UChar low)
+{
+ return (UChar32(high) << 10) + low - 0x35fdc00;
+}
+
+} // namespace Unicode
+} // namespace WTF
#endif // WTF_UnicodeWinCE_h
diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp b/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp
new file mode 100644
index 0000000..ee2014e
--- /dev/null
+++ b/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp
@@ -0,0 +1,173 @@
+// Copyright 2010, Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "URLCharacterTypes.h"
+
+namespace WTF {
+
+const unsigned char URLCharacterTypes::characterTypeTable[0x100] = {
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x00 - 0x0f
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x10 - 0x1f
+ InvalidCharacter, // 0x20 ' ' (escape spaces in queries)
+ QueryCharacter | UserInfoCharacter, // 0x21 !
+ InvalidCharacter, // 0x22 "
+ InvalidCharacter, // 0x23 # (invalid in query since it marks the ref)
+ QueryCharacter | UserInfoCharacter, // 0x24 $
+ QueryCharacter | UserInfoCharacter, // 0x25 %
+ QueryCharacter | UserInfoCharacter, // 0x26 &
+ QueryCharacter | UserInfoCharacter, // 0x27 '
+ QueryCharacter | UserInfoCharacter, // 0x28 (
+ QueryCharacter | UserInfoCharacter, // 0x29 )
+ QueryCharacter | UserInfoCharacter, // 0x2a *
+ QueryCharacter | UserInfoCharacter, // 0x2b +
+ QueryCharacter | UserInfoCharacter, // 0x2c ,
+ QueryCharacter | UserInfoCharacter, // 0x2d -
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x2e .
+ QueryCharacter, // 0x2f /
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x30 0
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x31 1
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x32 2
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x33 3
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x34 4
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x35 5
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x36 6
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x37 7
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x38 8
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x39 9
+ QueryCharacter, // 0x3a :
+ QueryCharacter, // 0x3b ;
+ InvalidCharacter, // 0x3c <
+ QueryCharacter, // 0x3d =
+ InvalidCharacter, // 0x3e >
+ QueryCharacter, // 0x3f ?
+ QueryCharacter, // 0x40 @
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x41 A
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x42 B
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x43 C
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x44 D
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x45 E
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x46 F
+ QueryCharacter | UserInfoCharacter, // 0x47 G
+ QueryCharacter | UserInfoCharacter, // 0x48 H
+ QueryCharacter | UserInfoCharacter, // 0x49 I
+ QueryCharacter | UserInfoCharacter, // 0x4a J
+ QueryCharacter | UserInfoCharacter, // 0x4b K
+ QueryCharacter | UserInfoCharacter, // 0x4c L
+ QueryCharacter | UserInfoCharacter, // 0x4d M
+ QueryCharacter | UserInfoCharacter, // 0x4e N
+ QueryCharacter | UserInfoCharacter, // 0x4f O
+ QueryCharacter | UserInfoCharacter, // 0x50 P
+ QueryCharacter | UserInfoCharacter, // 0x51 Q
+ QueryCharacter | UserInfoCharacter, // 0x52 R
+ QueryCharacter | UserInfoCharacter, // 0x53 S
+ QueryCharacter | UserInfoCharacter, // 0x54 T
+ QueryCharacter | UserInfoCharacter, // 0x55 U
+ QueryCharacter | UserInfoCharacter, // 0x56 V
+ QueryCharacter | UserInfoCharacter, // 0x57 W
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x58 X
+ QueryCharacter | UserInfoCharacter, // 0x59 Y
+ QueryCharacter | UserInfoCharacter, // 0x5a Z
+ QueryCharacter, // 0x5b [
+ QueryCharacter, // 0x5c '\'
+ QueryCharacter, // 0x5d ]
+ QueryCharacter, // 0x5e ^
+ QueryCharacter | UserInfoCharacter, // 0x5f _
+ QueryCharacter, // 0x60 `
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x61 a
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x62 b
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x63 c
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x64 d
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x65 e
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x66 f
+ QueryCharacter | UserInfoCharacter, // 0x67 g
+ QueryCharacter | UserInfoCharacter, // 0x68 h
+ QueryCharacter | UserInfoCharacter, // 0x69 i
+ QueryCharacter | UserInfoCharacter, // 0x6a j
+ QueryCharacter | UserInfoCharacter, // 0x6b k
+ QueryCharacter | UserInfoCharacter, // 0x6c l
+ QueryCharacter | UserInfoCharacter, // 0x6d m
+ QueryCharacter | UserInfoCharacter, // 0x6e n
+ QueryCharacter | UserInfoCharacter, // 0x6f o
+ QueryCharacter | UserInfoCharacter, // 0x70 p
+ QueryCharacter | UserInfoCharacter, // 0x71 q
+ QueryCharacter | UserInfoCharacter, // 0x72 r
+ QueryCharacter | UserInfoCharacter, // 0x73 s
+ QueryCharacter | UserInfoCharacter, // 0x74 t
+ QueryCharacter | UserInfoCharacter, // 0x75 u
+ QueryCharacter | UserInfoCharacter, // 0x76 v
+ QueryCharacter | UserInfoCharacter, // 0x77 w
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x78 x
+ QueryCharacter | UserInfoCharacter, // 0x79 y
+ QueryCharacter | UserInfoCharacter, // 0x7a z
+ QueryCharacter, // 0x7b {
+ QueryCharacter, // 0x7c |
+ QueryCharacter, // 0x7d }
+ QueryCharacter | UserInfoCharacter, // 0x7e ~
+ InvalidCharacter, // 0x7f
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x80 - 0x8f
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x90 - 0x9f
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xa0 - 0xaf
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xb0 - 0xbf
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xc0 - 0xcf
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xd0 - 0xdf
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xe0 - 0xef
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
+ InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xf0 - 0xff
+};
+
+}
diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.h b/JavaScriptCore/wtf/url/src/URLCharacterTypes.h
new file mode 100644
index 0000000..194f6b0
--- /dev/null
+++ b/JavaScriptCore/wtf/url/src/URLCharacterTypes.h
@@ -0,0 +1,61 @@
+// Copyright 2010, Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef URLCharacterTypes_h
+#define URLCharacterTypes_h
+
+namespace WTF {
+
+class URLCharacterTypes {
+public:
+ static inline bool isQueryChar(unsigned char c) { return isCharOfType(c, QueryCharacter); }
+ static inline bool isIPv4Char(unsigned char c) { return isCharOfType(c, IPv4Character); }
+ static inline bool isHexChar(unsigned char c) { return isCharOfType(c, HexCharacter); }
+
+private:
+ enum CharTypes {
+ InvalidCharacter = 0,
+ QueryCharacter = 1 << 0,
+ UserInfoCharacter = 1 << 1,
+ IPv4Character = 1 << 2,
+ HexCharacter = 1 << 3,
+ DecimalCharacter = 1 << 4,
+ OctalCharacter = 1 << 5,
+ };
+
+ static const unsigned char characterTypeTable[0x100];
+
+ static inline bool isCharOfType(unsigned char c, CharTypes type)
+ {
+ return !!(characterTypeTable[c] & type);
+ }
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/url/src/URLEscape.cpp b/JavaScriptCore/wtf/url/src/URLEscape.cpp
new file mode 100644
index 0000000..2987343
--- /dev/null
+++ b/JavaScriptCore/wtf/url/src/URLEscape.cpp
@@ -0,0 +1,39 @@
+// Copyright 2010, Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "URLEscape.h"
+
+namespace WTF {
+
+const char hexCharacterTable[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+};
+
+}
diff --git a/JavaScriptCore/wtf/url/src/URLEscape.h b/JavaScriptCore/wtf/url/src/URLEscape.h
new file mode 100644
index 0000000..cc2b77f
--- /dev/null
+++ b/JavaScriptCore/wtf/url/src/URLEscape.h
@@ -0,0 +1,49 @@
+// Copyright 2010, Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#ifndef URLEscape_h
+#define URLEscape_h
+
+#include "URLBuffer.h"
+
+namespace WTF {
+
+extern const char hexCharacterTable[16];
+
+template<typename InChar, typename OutChar>
+inline void appendURLEscapedCharacter(InChar ch, URLBuffer<OutChar>& buffer)
+{
+ buffer.append('%');
+ buffer.append(hexCharacterTable[ch >> 4]);
+ buffer.append(hexCharacterTable[ch & 0xf]);
+}
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h b/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h
new file mode 100644
index 0000000..7740200
--- /dev/null
+++ b/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h
@@ -0,0 +1,107 @@
+// Copyright 2010, Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#ifndef URLQueryCanonicalizer_h
+#define URLQueryCanonicalizer_h
+
+#include "RawURLBuffer.h"
+#include "URLBuffer.h"
+#include "URLCharacterTypes.h"
+#include "URLComponent.h"
+#include "URLEscape.h"
+
+namespace WTF {
+
+template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)>
+class URLQueryCanonicalizer {
+public:
+ static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery)
+ {
+ if (query.length() < 0) {
+ resultQuery = URLComponent();
+ return;
+ }
+
+ buffer->append('?');
+ resultQuery.setBegin(buffer->length());
+ convertToQueryEncoding(spec, query, buffer);
+ resultQuery.setLength(buffer->length() - resultQuery.begin());
+ }
+
+private:
+ static bool isAllASCII(const InChar* spec, const URLComponent& query)
+ {
+ int end = query.end();
+ for (int i = query.begin(); i < end; ++i) {
+ if (static_cast<unsigned>(spec[i]) >= 0x80)
+ return false;
+ }
+ return true;
+ }
+
+#ifndef NDEBUG
+ static bool isRaw8Bit(const InChar* source, int length)
+ {
+ for (int i = source; i < length; ++i) {
+ if (source[i] & 0xFF != source[i])
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer)
+ {
+ ASSERT(isRaw8Bit(source, length));
+ for (int i = 0; i < length; ++i) {
+ if (!URLCharacterTypes::isQueryChar(source[i]))
+ appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer);
+ else
+ buffer->append(static_cast<char>(source[i]));
+ }
+ }
+
+ static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer)
+ {
+ if (isAllASCII(spec, query)) {
+ appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer);
+ return;
+ }
+
+ RawURLBuffer<char, 1024> convertedQuery;
+ convertCharset(spec, query, convertedQuery);
+ appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer);
+ }
+};
+
+}
+
+#endif
+
+
diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri
index 84ac20e..83e71d8 100644
--- a/JavaScriptCore/wtf/wtf.pri
+++ b/JavaScriptCore/wtf/wtf.pri
@@ -6,6 +6,7 @@ SOURCES += \
wtf/CurrentTime.cpp \
wtf/DateMath.cpp \
wtf/dtoa.cpp \
+ wtf/DecimalNumber.cpp \
wtf/FastMalloc.cpp \
wtf/HashTable.cpp \
wtf/MD5.cpp \
@@ -22,6 +23,7 @@ SOURCES += \
wtf/WTFThreadData.cpp \
wtf/text/AtomicString.cpp \
wtf/text/CString.cpp \
+ wtf/text/StringBuilder.cpp \
wtf/text/StringImpl.cpp \
wtf/text/StringStatics.cpp \
wtf/text/WTFString.cpp \
diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp
index 17ffd8f..33f3c89 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -313,10 +313,24 @@ public:
if (!input.checkInput(matchSize))
return false;
- for (int i = 0; i < matchSize; ++i) {
- if (!checkCharacter(input.reread(matchBegin + i), inputOffset - matchSize + i)) {
- input.uncheckInput(matchSize);
- return false;
+ if (pattern->m_ignoreCase) {
+ for (int i = 0; i < matchSize; ++i) {
+ int ch = input.reread(matchBegin + i);
+
+ int lo = Unicode::toLower(ch);
+ int hi = Unicode::toUpper(ch);
+
+ if ((lo != hi) ? (!checkCasedCharacter(lo, hi, inputOffset - matchSize + i)) : (!checkCharacter(ch, inputOffset - matchSize + i))) {
+ input.uncheckInput(matchSize);
+ return false;
+ }
+ }
+ } else {
+ for (int i = 0; i < matchSize; ++i) {
+ if (!checkCharacter(input.reread(matchBegin + i), inputOffset - matchSize + i)) {
+ input.uncheckInput(matchSize);
+ return false;
+ }
}
}
@@ -481,6 +495,13 @@ public:
int matchBegin = output[(term.atom.subpatternId << 1)];
int matchEnd = output[(term.atom.subpatternId << 1) + 1];
+
+ // If the end position of the referenced match hasn't set yet then the backreference in the same parentheses where it references to that.
+ // In this case the result of match is empty string like when it references to a parentheses with zero-width match.
+ // Eg.: /(a\1)/
+ if (matchEnd == -1)
+ return true;
+
ASSERT((matchBegin == -1) == (matchEnd == -1));
ASSERT(matchBegin <= matchEnd);
@@ -1497,7 +1518,7 @@ public:
m_currentAlternativeIndex = newAlternativeIndex;
}
- void emitDisjunction(PatternDisjunction* disjunction, unsigned inputCountAlreadyChecked = 0, unsigned parenthesesInputCountAlreadyChecked = 0)
+ void emitDisjunction(PatternDisjunction* disjunction, unsigned inputCountAlreadyChecked = 0, unsigned parenthesesInputCountAlreadyChecked = 0, bool isParentheticalAssertion = false)
{
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
unsigned currentCountAlreadyChecked = inputCountAlreadyChecked;
@@ -1512,12 +1533,18 @@ public:
}
unsigned minimumSize = alternative->m_minimumSize;
+ int countToCheck;
- ASSERT(minimumSize >= parenthesesInputCountAlreadyChecked);
- unsigned countToCheck = minimumSize - parenthesesInputCountAlreadyChecked;
- if (countToCheck)
+ if (isParentheticalAssertion && parenthesesInputCountAlreadyChecked > minimumSize)
+ countToCheck = 0;
+ else
+ countToCheck = minimumSize - parenthesesInputCountAlreadyChecked;
+
+ ASSERT(countToCheck >= 0);
+ if (countToCheck) {
checkInput(countToCheck);
- currentCountAlreadyChecked += countToCheck;
+ currentCountAlreadyChecked += countToCheck;
+ }
for (unsigned i = 0; i < alternative->m_terms.size(); ++i) {
PatternTerm& term = alternative->m_terms[i];
@@ -1577,8 +1604,11 @@ public:
case PatternTerm::TypeParentheticalAssertion: {
unsigned alternativeFrameLocation = term.frameLocation + RegexStackSpaceForBackTrackInfoParentheticalAssertion;
+ ASSERT(currentCountAlreadyChecked >= (unsigned)term.inputPosition);
+ int positiveInputOffset = currentCountAlreadyChecked - term.inputPosition;
+
atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation);
- emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
+ emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, positiveInputOffset, true);
atomParenthesesEnd(true, term.parentheses.lastSubpatternId, 0, term.frameLocation, term.quantityCount, term.quantityType);
break;
}