diff options
author | Steve Block <steveblock@google.com> | 2010-07-08 12:51:48 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-07-09 15:33:40 +0100 |
commit | ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24 (patch) | |
tree | bb45155550ec013adc0ad10f4d7d354c6469b022 /JavaScriptCore | |
parent | d4b24d9a829ed7de70381c8b99fb75a07ab40466 (diff) | |
download | external_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.zip external_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.tar.gz external_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.tar.bz2 |
Merge WebKit at r62496: Initial merge by git
Change-Id: Ie3da0770eca22a70a632e3571f31cfabc80facb2
Diffstat (limited to 'JavaScriptCore')
80 files changed, 3577 insertions, 3364 deletions
diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c index 780e996..183abf5 100644 --- a/JavaScriptCore/API/tests/testapi.c +++ b/JavaScriptCore/API/tests/testapi.c @@ -927,7 +927,8 @@ int main(int argc, char* argv[]) JSStringRelease(EmptyObjectIString); JSStringRef lengthStr = JSStringCreateWithUTF8CString("length"); - aHeapRef = JSObjectMakeArray(context, 0, 0, 0); + JSObjectRef aStackRef = JSObjectMakeArray(context, 0, 0, 0); + aHeapRef = aStackRef; JSObjectSetProperty(context, aHeapRef, lengthStr, JSValueMakeNumber(context, 10), 0, 0); JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty"); if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) { @@ -936,6 +937,7 @@ int main(int argc, char* argv[]) } else { printf("PASS: Set private property.\n"); } + aStackRef = 0; if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) { printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n"); failed = 1; @@ -964,6 +966,7 @@ int main(int argc, char* argv[]) for (int i = 0; i < 10000; i++) JSObjectMake(context, 0, 0); + aHeapRef = JSValueToObject(context, JSObjectGetPrivateProperty(context, myObject, privatePropertyName), 0); if (JSValueToNumber(context, JSObjectGetProperty(context, aHeapRef, lengthStr, 0), 0) != 10) { printf("FAIL: Private property has been collected.\n"); failed = 1; diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk index ded912e..42df087 100644 --- a/JavaScriptCore/Android.mk +++ b/JavaScriptCore/Android.mk @@ -196,14 +196,6 @@ LOCAL_SRC_FILES := \ yarr/RegexInterpreter.cpp \ yarr/RegexJIT.cpp -# Rule to build grammar.y with our custom bison. -GEN := $(intermediates)/parser/Grammar.cpp -$(GEN) : PRIVATE_YACCFLAGS := -p jscyy -$(GEN) : $(LOCAL_PATH)/parser/Grammar.y - $(call local-transform-y-to-cpp,.cpp) -$(GEN) : $(LOCAL_BISON) -LOCAL_GENERATED_SOURCES += $(GEN) - # generated headers JSC_OBJECTS := $(addprefix $(intermediates)/runtime/, \ ArrayPrototype.lut.h \ diff --git a/JavaScriptCore/CMakeLists.txt b/JavaScriptCore/CMakeLists.txt index c1946ff..bdb1467 100644 --- a/JavaScriptCore/CMakeLists.txt +++ b/JavaScriptCore/CMakeLists.txt @@ -203,17 +203,6 @@ ENDFOREACH () GENERATE_HASH_LUT(${JAVASCRIPTCORE_DIR}/parser/Keywords.table ${DERIVED_SOURCES_DIR}/Lexer.lut.h MAIN_DEPENDENCY) LIST(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_DIR}/Lexer.lut.h) -# GENERATOR 2: bison grammar -ADD_CUSTOM_COMMAND( - OUTPUT ${DERIVED_SOURCES_DIR}/Grammar.cpp ${DERIVED_SOURCES_DIR}/Grammar.h - MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/parser/Grammar.y - COMMAND ${BISON_EXECUTABLE} -d -p jscyy ${JAVASCRIPTCORE_DIR}/parser/Grammar.y -o ${DERIVED_SOURCES_DIR}/Grammar.cpp --defines=${DERIVED_SOURCES_DIR}/Grammar.h - COMMENT "[BISON][JSCYY] Building parser with bison" - VERBATIM) -LIST(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_DIR}/Grammar.h) -LIST(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/Grammar.cpp) - - # GENERATOR: "chartables.c": compile and execute the chartables generator (and add it to sources) IF (MSVC) SET(JSC_DFTABLES_PREPROCESSOR --preprocessor=cl.exe) diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index ff017ca..c6cbd6d 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,811 @@ +2010-07-05 Steve Block <steveblock@google.com> + + Reviewed by Darin Adler. + + ThreadingPthreads.cpp should use JNIUtility.h on Android, not outdated jni_utility.h + https://bugs.webkit.org/show_bug.cgi?id=41594 + + * wtf/ThreadingPthreads.cpp: + +2010-07-04 Mark Rowe <mrowe@apple.com> + + Build fix after r62456. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): Be slightly more consistent in using uint32_t to prevent + warnings about comparisons between signed and unsigned types, and attempts to call an overload + of std::min that doesn't exist. + +2010-07-02 Sam Weinig <sam@webkit.org> + + Reviewed by Darin Adler. + + Patch for https://bugs.webkit.org/show_bug.cgi?id=41553 + Make StringExtras.h versions of snprintf and vsnprintf match the unix versions. + + - MSVC does not ensure the buffers are null terminated as the unix versions do. + + * runtime/JSGlobalObjectFunctions.cpp: Cleanup includes. + * runtime/UString.cpp: Clean up includes. + (JSC::UString::from): Don't pass sizeof(buf) - 1, that is wrong. + * wtf/StringExtras.h: + (snprintf): Ensure null termination of buffer. + (vsnprintf): Ditto. + +2010-07-03 Yong Li <yoli@rim.com> + + Reviewed by Darin Adler. + + Make Arguments::MaxArguments clamping work for numbers >= 0x80000000 in + the interpreter as well as the JIT. + + https://bugs.webkit.org/show_bug.cgi?id=41351 + rdar://problem/8142141 + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): Fix signed integer overflow problem + in op_load_varargs handling. 0xFFFFFFFF was read as -1. + +2010-06-26 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Dumitru Daniliuc. + + Support for keys and in-memory storage for IndexedDB + https://bugs.webkit.org/show_bug.cgi?id=41252 + + Set the role to Private. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2010-07-02 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoffrey Garen. + + Move BOM handling out of the lexer and parser + https://bugs.webkit.org/show_bug.cgi?id=41539 + + Doing the BOM stripping in the lexer meant that we could + end up having to strip the BOMs from a source multiple times. + To deal with this we now require all strings provided by + a SourceProvider to already have had the BOMs stripped. + This also simplifies some of the lexer logic. + + * parser/Lexer.cpp: + (JSC::Lexer::setCode): + (JSC::Lexer::sourceCode): + * parser/SourceProvider.h: + (JSC::SourceProvider::SourceProvider): + (JSC::UStringSourceProvider::create): + (JSC::UStringSourceProvider::getRange): + (JSC::UStringSourceProvider::UStringSourceProvider): + * wtf/text/StringImpl.h: + (WebCore::StringImpl::copyStringWithoutBOMs): + +2010-07-03 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Kent Tamura. + + [WINCE] Implement Unicode::isAlphanumeric and Unicode::isArabicChar. + https://bugs.webkit.org/show_bug.cgi?id=41411 + + * wtf/unicode/wince/UnicodeWince.cpp: + (WTF::Unicode::isAlphanumeric): + * wtf/unicode/wince/UnicodeWince.h: + (WTF::Unicode::isArabicChar): + +2010-07-03 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Kent Tamura. + + [BREWMP] Change the CRASH() macro to print "WebKit CRASH" log. + https://bugs.webkit.org/show_bug.cgi?id=41524 + + Print "WebKit CRASH" before crashing. + + * wtf/Assertions.h: + +2010-07-02 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 41565 - Repatching in ARMv7Assembler::repatchLoadPtrToLEA is broken + + This method tried to repatch a LDR (T2) into an ADD (T3) - but it only + repatches the first instruction word. The layout of the fields in the + second word is different, and also needs repatching. + + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::repatchLoadPtrToLEA): + +2010-07-02 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Clamp the number of arguments supported by function.apply + https://bugs.webkit.org/show_bug.cgi?id=41351 + <rdar://problem/8142141> + + Add clamping logic to function.apply similar to that + enforced by firefox. We have a smaller clamp than + firefox as our calling convention means that stack + usage is proportional to argument count -- the firefox + limit is larger than you could actually call. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Arguments.h: + (JSC::Arguments::): + +2010-07-02 Chao-ying Fu <fu@mips.com> + + Reviewed by Oliver Hunt. + + Re-enable JIT_OPTIMIZE_NATIVE_CALL on MIPS + https://bugs.webkit.org/show_bug.cgi?id=40179 + + Add the MIPS part to re-enable JIT_OPTIMIZE_NATIVE_CALL. + + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTINativeCall): + * wtf/Platform.h: + +2010-07-02 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 41552 - Clean up ARMv7 vfp code generation + Emit separate opcode individually, remove magic numbers. + + Also remove invalid assert from JSImmediate (number cells are not CELL_MASK aligned). + + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::): + (JSC::ARMv7Assembler::vadd_F64): + (JSC::ARMv7Assembler::vcmp_F64): + (JSC::ARMv7Assembler::vcvt_F64_S32): + (JSC::ARMv7Assembler::vcvtr_S32_F64): + (JSC::ARMv7Assembler::vdiv_F64): + (JSC::ARMv7Assembler::vldr): + (JSC::ARMv7Assembler::vmov_F64_0): + (JSC::ARMv7Assembler::vmov): + (JSC::ARMv7Assembler::vmrs): + (JSC::ARMv7Assembler::vmul_F64): + (JSC::ARMv7Assembler::vstr): + (JSC::ARMv7Assembler::vsub_F64): + (JSC::ARMv7Assembler::VFPOperand::VFPOperand): + (JSC::ARMv7Assembler::VFPOperand::bits1): + (JSC::ARMv7Assembler::VFPOperand::bits4): + (JSC::ARMv7Assembler::vcvtOp): + (JSC::ARMv7Assembler::ARMInstructionFormatter::vfpOp): + (JSC::ARMv7Assembler::ARMInstructionFormatter::vfpMemOp): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::branchDouble): + * runtime/JSImmediate.h: + (JSC::JSValue::isCell): + +2010-07-02 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r62410. + http://trac.webkit.org/changeset/62410 + https://bugs.webkit.org/show_bug.cgi?id=41549 + + accursed last minute changes (Requested by olliej on #webkit). + + * parser/Lexer.cpp: + (JSC::Lexer::setCode): + (JSC::Lexer::copyCodeWithoutBOMs): + (JSC::Lexer::sourceCode): + * parser/SourceProvider.h: + (JSC::): + (JSC::SourceProvider::SourceProvider): + (JSC::SourceProvider::hasBOMs): + (JSC::UStringSourceProvider::create): + (JSC::UStringSourceProvider::getRange): + (JSC::UStringSourceProvider::UStringSourceProvider): + * wtf/text/StringImpl.h: + +2010-07-02 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Patch for https://bugs.webkit.org/show_bug.cgi?id=41548 + Use snprintf instead of sprintf everywhere in JavaScriptCore + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::globalFuncEscape): + * runtime/UString.cpp: + (JSC::UString::from): + +2010-07-02 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoffrey Garen. + + Move BOM handling out of the lexer and parser + https://bugs.webkit.org/show_bug.cgi?id=41539 + + Doing the BOM stripping in the lexer meant that we could + end up having to strip the BOMs from a source multiple times. + To deal with this we now require all strings provided by + a SourceProvider to already have had the BOMs stripped. + This also simplifies some of the lexer logic. + + * parser/Lexer.cpp: + (JSC::Lexer::setCode): + (JSC::Lexer::sourceCode): + * parser/SourceProvider.h: + (JSC::SourceProvider::SourceProvider): + (JSC::UStringSourceProvider::create): + (JSC::UStringSourceProvider::getRange): + (JSC::UStringSourceProvider::UStringSourceProvider): + * wtf/text/StringImpl.h: + (WebCore::StringImpl::copyStringWithoutBOMs): + +2010-07-02 Renata Hodovan <reni@inf.u-szeged.hu> + + Reviewed by Oliver Hunt. + + [ Updated after rollout. ] + + Merged RegExp constructor and RegExp::create methods. + Both functions are called with three parameters and check whether + flags (the third param) is given or not. + Avoid extra hash lookups in RegExpCache::create by passing a pre-computed + iterator parameter. + https://bugs.webkit.org/show_bug.cgi?id=41055 + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExp.h: + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::lookupOrCreate): + (JSC::RegExpCache::create): + * runtime/RegExpCache.h: + +2010-07-02 Martin Robinson <mrobinson@igalia.com> + + Unreviewed. Build fix for GTK+. + + Build Lexer.lut.h with the rest of the .lut.h files. Later these should + all probably be moved to DerivedSources. + + * GNUmakefile.am: + +2010-06-23 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] Separate DerivedSources per-project + https://bugs.webkit.org/show_bug.cgi?id=41109 + + Generate JavaScriptCore derived sources in <builddir>/DerivedSources/JavaScriptCore. + + * GNUmakefile.am: + +2010-07-02 Peter Varga <pvarga@inf.u-szeged.hu> + + Reviewed by Oliver Hunt. + + The alternativeFrameLocation value is wrong in the emitDisjunction function in + case of PatternTerm::TypeParentheticalAssertion. This value needs to be + computed from term.frameLocation instead of term.inputPosition. This mistake caused glibc + memory corruption in some cases. + Layout test added for checking of TypeParentheticalAssertion case. + https://bugs.webkit.org/show_bug.cgi?id=41458 + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::ByteCompiler::emitDisjunction): + +2010-07-01 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Add a FixedArray template to encapsulate fixed length arrays + https://bugs.webkit.org/show_bug.cgi?id=41506 + + This new type is used in place of fixed length C arrays so + that debug builds can guard against attempts to go beyond + the end of the array. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.cpp: + (JSC::OpcodeStats::~OpcodeStats): + * pcre/pcre_compile.cpp: + (calculateCompiledPatternLength): + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): + (JSC::Heap::allocate): + * runtime/Collector.h: + (JSC::CollectorBitmap::clearAll): + * runtime/CollectorHeapIterator.h: + (JSC::CollectorHeapIterator::operator*): + * runtime/DateInstanceCache.h: + * runtime/JSString.cpp: + (JSC::JSString::replaceCharacter): + * runtime/JSString.h: + (JSC::RopeBuilder::JSStringFinalizerStruct::): + * runtime/NumericStrings.h: + * runtime/RegExpCache.h: + * runtime/SmallStrings.h: + (JSC::SmallStrings::singleCharacterStrings): + * wtf/AVLTree.h: + * wtf/FixedArray.h: Added. + (WTF::FixedArray::operator[]): + (WTF::FixedArray::data): + +2010-07-01 Zoltan Herczeg <zherczeg@webkit.org> + + Reviewed by Oliver Hunt. + + Improve the main lexer switch by mapping input characters to their type + https://bugs.webkit.org/show_bug.cgi?id=41459 + + Sunsipder: no change (from 532.9ms to 531.5ms) + SunSpider --parse-only: 1.025x as fast (from 33.1ms to 32.3ms) + + * parser/Lexer.cpp: + (JSC::): + (JSC::Lexer::lex): + +2010-07-01 Sam Weinig <sam@webkit.org> + + Rubber-stamped by Ander Carlsson. + + Define HAVE_HOSTED_CORE_ANIMATION on Snow Leopard. + + * wtf/Platform.h: + +2010-07-01 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 41490 - Add missing operations to MacroAssemblerARMv7 + Also, make single, double, quad register numbers in ARMv7Assembler distinct & strongly typed. + + * assembler/ARMv7Assembler.h: + (JSC::ARMRegisters::): + (JSC::ARMRegisters::asSingle): + (JSC::ARMRegisters::asDouble): + (JSC::VFPImmediate::VFPImmediate): + (JSC::VFPImmediate::isValid): + (JSC::VFPImmediate::value): + (JSC::ARMv7Assembler::singleRegisterMask): + (JSC::ARMv7Assembler::doubleRegisterMask): + (JSC::ARMv7Assembler::): + (JSC::ARMv7Assembler::add_S): + (JSC::ARMv7Assembler::neg): + (JSC::ARMv7Assembler::orr_S): + (JSC::ARMv7Assembler::sub): + (JSC::ARMv7Assembler::sub_S): + (JSC::ARMv7Assembler::vadd_F64): + (JSC::ARMv7Assembler::vcmp_F64): + (JSC::ARMv7Assembler::vcvt_F64_S32): + (JSC::ARMv7Assembler::vcvtr_S32_F64): + (JSC::ARMv7Assembler::vdiv_F64): + (JSC::ARMv7Assembler::vldr): + (JSC::ARMv7Assembler::vmov_F64_0): + (JSC::ARMv7Assembler::vmov): + (JSC::ARMv7Assembler::vmul_F64): + (JSC::ARMv7Assembler::vstr): + (JSC::ARMv7Assembler::vsub_F64): + (JSC::ARMv7Assembler::vcvt): + (JSC::ARMv7Assembler::vmem): + * assembler/AbstractMacroAssembler.h: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::fpTempRegisterAsSingle): + (JSC::MacroAssemblerARMv7::neg32): + (JSC::MacroAssemblerARMv7::loadDouble): + (JSC::MacroAssemblerARMv7::divDouble): + (JSC::MacroAssemblerARMv7::convertInt32ToDouble): + (JSC::MacroAssemblerARMv7::branchConvertDoubleToInt32): + (JSC::MacroAssemblerARMv7::zeroDouble): + (JSC::MacroAssemblerARMv7::branchOr32): + (JSC::MacroAssemblerARMv7::set32): + (JSC::MacroAssemblerARMv7::set8): + * assembler/MacroAssemblerMIPS.h: + * assembler/MacroAssemblerX86Common.h: + +2010-07-01 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Improve reentrancy logic in polymorphic cache stubs + <https://bugs.webkit.org/show_bug.cgi?id=41482> + <rdar://problem/8094380> + + Make the polymorphic cache stubs handle reentrancy + better. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + (JSC::getPolymorphicAccessStructureListSlot): + +2010-07-01 Antti Koivisto <koivisto@iki.fi> + + Revert accidental commit. + + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): + +2010-06-30 Darin Adler <darin@apple.com> + + Reviewed by Adam Barth. + + Add assertion, off by default, for when you forget to do adoptRef + https://bugs.webkit.org/show_bug.cgi?id=41422 + + * wtf/PassRefPtr.h: Tweaked formatting. Added a new adopted + function, called on the pointer by adoptRef, with an empty inline + default version, meant to be overloaded. Unified the inlining + with a macro named REF_DEREF_INLINE to make it clearer what's + going on in the refIfNotNull/derefIfNotNull functions. Renamed + releaseRef to leakRef, but left the old name in for compatibility + for now. + + * wtf/RefCounted.h: Added code to require adoption and assert if + you don't call adoptRef. For now, it is turned off because of the + LOOSE_REF_COUNTED define in this header. Later we can turn it on + once we get everything working without asserting. + +2010-06-29 Michael Saboff <msaboff@apple.com> + + Reviewed by Darin Adler. + + Bug 41238 - RegExp performance slow on Dromaeo benchmark + + Other javascript engines appear to cache prior results of regular + expression operations. + + Suggest adding some sort of caching mechanism to regular expression + processing. + + Added a single entry cache of match() results to RegExp class. + + Also added performance improvements to UString == operator. + First check the impls for equality. Then get the length of + each of the non-null impls. Next check the sizes for equality. + Then check the data for the case of different impls that point + to the same data (most likely due to substrings from the beginning of + another string). Lastly we check the underlying data for equality. + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + (JSC::RegExp::match): + * runtime/RegExp.h: + * runtime/UString.h: + (JSC::operator==): + +2010-06-29 Nathan Lawrence <nlawrence@apple.com> + + Reviewed by Geoffrey Garen. + + WTF::HashSet iterators are quasi-mutable. Changing the value through + dereferencing an iterator will not change the behavior of methods like + contains or find, but will change the behavior of iterating. + + * wtf/HashSet.h: + (WTF::::begin): + (WTF::::end): + (WTF::::find): + (WTF::::remove): + * wtf/HashTable.h: + +2010-06-29 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Clean up the source lists in the GNUMakefile.am files + https://bugs.webkit.org/show_bug.cgi?id=41229 + + Clean up the GNUMakefile.am a little bit. Alphabetize and conglomerate + the source lists. + + * GNUmakefile.am: + +2010-06-29 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix QtScript build after QScriptValuePrivate ctor changes + https://bugs.webkit.org/show_bug.cgi?id=41307 + + * qt/api/qscriptvalue_p.h: + (QScriptValuePrivate::prototype): + * qt/benchmarks/qscriptengine/qscriptengine.pro: + +2010-06-28 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QScriptEngine API should contain a newArray function + https://bugs.webkit.org/show_bug.cgi?id=39115 + + * qt/api/qscriptengine.cpp: + (QScriptEngine::newArray): + * qt/api/qscriptengine.h: + * qt/api/qscriptengine_p.cpp: + (QScriptEnginePrivate::newArray): + * qt/api/qscriptengine_p.h: + * qt/tests/qscriptengine/tst_qscriptengine.cpp: + (tst_QScriptEngine::newArray): + +2010-06-28 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + Install jsc as jsc-X where X is the major API version to allow + parallel installation of both GTK+ 2.x and 3.x versions. + + * GNUmakefile.am: + +2010-06-28 John Gregg <johnnyg@google.com> + + Reviewed by Kent Tamura. + + add ENABLE_DIRECTORY_UPLOAD build support + https://bugs.webkit.org/show_bug.cgi?id=41100 + + * Configurations/FeatureDefines.xcconfig: + +2010-06-28 Xan Lopez <xlopez@igalia.com> + + Revert to build jsc, since the tests expect this. + + * GNUmakefile.am: + +2010-06-28 Zoltan Herczeg <zherczeg@webkit.org> + + Reviewed by Oliver Hunt. + + Only one character lookahead should be enough for the lexer + https://bugs.webkit.org/show_bug.cgi?id=41213 + + The lexer had 4 character lookahead before, which required + a complex shifting mechanism. This can be improved by using + only one character lookahead for most decisions, and a + peek() function as a fallback when it is absolutely necessary. + + * parser/Lexer.cpp: + (JSC::Lexer::currentCharacter): + (JSC::Lexer::currentOffset): + (JSC::Lexer::setCode): + (JSC::Lexer::shift): + (JSC::Lexer::peek): + (JSC::Lexer::getUnicodeCharacter): + (JSC::Lexer::shiftLineTerminator): + (JSC::Lexer::lastTokenWasRestrKeyword): + (JSC::Lexer::lex): + (JSC::Lexer::scanRegExp): + (JSC::Lexer::skipRegExp): + * parser/Lexer.h: + +2010-06-28 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Unreviewed build fix. + + [EFL] Build fix for latest version of Ecore library. + Ecore recently changed return type of callbacks from int to Eina_Bool. + + * wtf/efl/MainThreadEfl.cpp: + (WTF::timeoutFired): Return Eina_Bool instead of int. + +2010-06-28 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QScriptValue should have API for accessing object properties + https://bugs.webkit.org/show_bug.cgi?id=40903 + + Make possible to access properties inside QScriptValues. While this + still doesn't support the ResolveLocal parameter, it is already useful + for testing the API. + + The tests from upstream QtScript weren't imported since most of them + depend on the setProperty() function as well. A simple test was created. + + * qt/api/qscriptvalue.cpp: + (QScriptValue::property): + * qt/api/qscriptvalue.h: + (QScriptValue::): + * qt/api/qscriptvalue_p.h: + (QScriptValuePrivate::property): + * qt/tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::propertySimple): + * qt/tests/qscriptvalue/tst_qscriptvalue.h: + +2010-06-28 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + [GTK] Add support for GTK+3 + https://bugs.webkit.org/show_bug.cgi?id=41253 + + Suffix jsc with the API version of the library, so that + libwebkitgtk 1.x and 3.x can install jsc. + + * GNUmakefile.am: + +2010-06-27 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Kent Tamura. + + [BREWMP] Turn ENABLE(SINGLE_THREADED) on. + https://bugs.webkit.org/show_bug.cgi?id=41135 + + Brew MP does not support preemptive multi-threading. + Disable threading for Brew MP. + + * wtf/Platform.h: + +2010-06-26 Tony Gentilcore <tonyg@chromium.org> + + Reviewed by Dimitri Glazkov. + + Add an ENABLE_WEB_TIMING option for enabling Web Timing support. + https://bugs.webkit.org/show_bug.cgi?id=38924 + + * Configurations/FeatureDefines.xcconfig: + +2010-06-25 Nathan Lawrence <nlawrence@apple.com> + + Reviewed by Geoffrey Garen. + + We assume in testapi.c that the value aHeapRef refers to will not be + moved. When we have movable objects, this will not be the case. + + * API/tests/testapi.c: + (main): + +2010-06-25 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r61924. + http://trac.webkit.org/changeset/61924 + https://bugs.webkit.org/show_bug.cgi?id=41240 + + It was rolled out, but cq+ wasn't removed (Requested by Ossy_ + on #webkit). + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + (JSC::RegExp::create): + * runtime/RegExp.h: + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::lookupOrCreate): + (JSC::RegExpCache::create): + * runtime/RegExpCache.h: + +2010-06-25 Renata Hodovan <reni@inf.u-szeged.hu> + + Reviewed by Geoffrey Garen. + + Merge RegExp constructor and RegExp::create methods into one. + Both of function are called with tree parameters and check whether + flags (the third param) is given or not. + Simplify hash lookups in RegExpCache::create with giving them an extra + iterator parameter. + https://bugs.webkit.org/show_bug.cgi?id=41055 + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExp.h: + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::lookupOrCreate): + (JSC::RegExpCache::create): + * runtime/RegExpCache.h: + +2010-06-25 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Introduce QtScript benchmarks. + + The QtScript performance should be tested regularly. The patch introduces + micro benchmarks for existing API. + + [Qt] Performance of the QtScript API is not tested. + https://bugs.webkit.org/show_bug.cgi?id=40911 + + * qt/benchmarks/benchmarks.pri: Copied from JavaScriptCore/qt/tests/tests.pri. + * qt/benchmarks/benchmarks.pro: Added. + * qt/benchmarks/qscriptengine/qscriptengine.pro: Added. + * qt/benchmarks/qscriptengine/tst_qscriptengine.cpp: Added. + (tst_QScriptEngine::checkSyntax_data): + (tst_QScriptEngine::checkSyntax): + (tst_QScriptEngine::constructor): + (tst_QScriptEngine::evaluateString_data): + (tst_QScriptEngine::evaluateString): + (tst_QScriptEngine::evaluateProgram_data): + (tst_QScriptEngine::evaluateProgram): + (tst_QScriptEngine::newObject): + (tst_QScriptEngine::nullValue): + (tst_QScriptEngine::undefinedValue): + (tst_QScriptEngine::globalObject): + (tst_QScriptEngine::toStringHandle): + * qt/benchmarks/qscriptvalue/qscriptvalue.pro: Added. + * qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp: Added. + (tst_QScriptValue::tst_QScriptValue): + (tst_QScriptValue::~tst_QScriptValue): + (tst_QScriptValue::values_data): + (tst_QScriptValue::ctorBool): + (tst_QScriptValue::ctorReal): + (tst_QScriptValue::ctorNumber): + (tst_QScriptValue::ctorQString): + (tst_QScriptValue::ctorCString): + (tst_QScriptValue::ctorSpecial): + (tst_QScriptValue::ctorQScriptValue): + (tst_QScriptValue::isValid_data): + (tst_QScriptValue::isValid): + (tst_QScriptValue::isBool_data): + (tst_QScriptValue::isBool): + (tst_QScriptValue::isNumber_data): + (tst_QScriptValue::isNumber): + (tst_QScriptValue::isFunction_data): + (tst_QScriptValue::isFunction): + (tst_QScriptValue::isNull_data): + (tst_QScriptValue::isNull): + (tst_QScriptValue::isString_data): + (tst_QScriptValue::isString): + (tst_QScriptValue::isUndefined_data): + (tst_QScriptValue::isUndefined): + (tst_QScriptValue::isObject_data): + (tst_QScriptValue::isObject): + (tst_QScriptValue::isError_data): + (tst_QScriptValue::isError): + (tst_QScriptValue::toString_data): + (tst_QScriptValue::toString): + (tst_QScriptValue::toNumber_data): + (tst_QScriptValue::toNumber): + (tst_QScriptValue::toBool_data): + (tst_QScriptValue::toBool): + (tst_QScriptValue::toInteger_data): + (tst_QScriptValue::toInteger): + (tst_QScriptValue::toInt32_data): + (tst_QScriptValue::toInt32): + (tst_QScriptValue::toUInt32_data): + (tst_QScriptValue::toUInt32): + (tst_QScriptValue::toUInt16_data): + (tst_QScriptValue::toUInt16): + (tst_QScriptValue::toObject_data): + (tst_QScriptValue::toObject): + (tst_QScriptValue::equals_data): + (tst_QScriptValue::equals): + (tst_QScriptValue::strictlyEquals_data): + (tst_QScriptValue::strictlyEquals): + (tst_QScriptValue::instanceOf_data): + (tst_QScriptValue::instanceOf): + +2010-06-25 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoffrey Garen. + + Remove old js parser + https://bugs.webkit.org/show_bug.cgi?id=41222 + + Remove the old yacc parser, this also solves the tiger problem. Which + was a conflict between yacc generated token values and those in the + custom parser + + * Android.mk: + * CMakeLists.txt: + * DerivedSources.make: + * DerivedSources.pro: + * GNUmakefile.am: + * JavaScriptCore.pro: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * parser/Grammar.y: Removed. + * parser/JSParser.cpp: + * parser/JSParser.h: + * parser/Lexer.cpp: + * parser/NodeConstructors.h: + (JSC::Node::Node): + * parser/Parser.cpp: + (JSC::Parser::parse): + * wtf/Platform.h: + 2010-06-25 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> Reviewed by Simon Hausmann. diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig index 08d9ef9..8f86fc3 100644 --- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -48,6 +48,7 @@ ENABLE_DATABASE = ENABLE_DATABASE; ENABLE_DATAGRID = ; ENABLE_DATALIST = ENABLE_DATALIST; ENABLE_DEVICE_ORIENTATION = ; +ENABLE_DIRECTORY_UPLOAD = ; ENABLE_DOM_STORAGE = ENABLE_DOM_STORAGE; ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE; ENABLE_FILTERS = ENABLE_FILTERS; @@ -76,10 +77,12 @@ ENABLE_SVG_FOREIGN_OBJECT = ENABLE_SVG_FOREIGN_OBJECT; ENABLE_SVG_USE = ENABLE_SVG_USE; ENABLE_VIDEO = ENABLE_VIDEO; ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS; +ENABLE_WEB_TIMING = ; ENABLE_WML = ; ENABLE_WORKERS = ENABLE_WORKERS; ENABLE_XHTMLMP = ; ENABLE_XPATH = ENABLE_XPATH; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB_SLICE) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_READER) $(ENABLE_FILE_WRITER) $(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_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB_SLICE) $(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_READER) $(ENABLE_FILE_WRITER) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT); + diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index f775a54..2749545 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 = 2; +MINOR_VERSION = 3; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/JavaScriptCore/DerivedSources.make b/JavaScriptCore/DerivedSources.make index 37020f1..2e8adb4 100644 --- a/JavaScriptCore/DerivedSources.make +++ b/JavaScriptCore/DerivedSources.make @@ -39,7 +39,6 @@ all : \ ArrayPrototype.lut.h \ chartables.c \ DatePrototype.lut.h \ - Grammar.cpp \ JSONObject.lut.h \ Lexer.lut.h \ MathObject.lut.h \ @@ -61,16 +60,6 @@ all : \ Lexer.lut.h: create_hash_table Keywords.table $^ > $@ -# JavaScript language grammar - -Grammar.cpp: Grammar.y - bison -d -p jscyy $< -o $@ > bison_out.txt 2>&1 - perl -p -e 'END { if ($$conflict) { unlink "Grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt - touch Grammar.cpp.h - touch Grammar.hpp - cat Grammar.cpp.h Grammar.hpp > Grammar.h - rm -f Grammar.cpp.h Grammar.hpp bison_out.txt - # character tables for PCRE chartables.c : dftables diff --git a/JavaScriptCore/DerivedSources.pro b/JavaScriptCore/DerivedSources.pro index 7c5aad8..f358c8b 100644 --- a/JavaScriptCore/DerivedSources.pro +++ b/JavaScriptCore/DerivedSources.pro @@ -26,9 +26,6 @@ LUT_FILES += \ KEYWORDLUT_FILES += \ parser/Keywords.table -JSCBISON += \ - parser/Grammar.y - RVCT_STUB_FILES += \ jit/JITStubs.cpp @@ -68,13 +65,6 @@ keywordlut.commands = perl $$keywordlut.wkScript ${QMAKE_FILE_NAME} -i > ${QMAKE keywordlut.depends = ${QMAKE_FILE_NAME} addExtraCompiler(keywordlut) -# GENERATOR 2: bison grammar -jscbison.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.cpp -jscbison.input = JSCBISON -jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c && $(MOVE) $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.h $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.h -jscbison.depends = ${QMAKE_FILE_NAME} -addExtraCompiler(jscbison) - # GENERATOR 3: JIT Stub functions for RVCT rvctstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_RVCT.h rvctstubs.wkScript = $$PWD/create_jit_stubs diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index 957c743..aefc4fb 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -34,7 +34,7 @@ javascriptcore_h_api += \ JavaScriptCore/API/WebKitAvailability.h javascriptcore_built_nosources += \ - DerivedSources/Lexer.lut.h \ + JavaScriptCore/Lexer.lut.h \ JavaScriptCore/RegExpJitTables.h \ JavaScriptCore/runtime/ArrayPrototype.lut.h \ JavaScriptCore/runtime/DatePrototype.lut.h \ @@ -56,8 +56,8 @@ javascriptcore_sources += \ JavaScriptCore/API/JSCallbackFunction.cpp \ JavaScriptCore/API/JSCallbackFunction.h \ JavaScriptCore/API/JSCallbackObject.cpp \ - JavaScriptCore/API/JSCallbackObject.h \ JavaScriptCore/API/JSCallbackObjectFunctions.h \ + JavaScriptCore/API/JSCallbackObject.h \ JavaScriptCore/API/JSClassRef.cpp \ JavaScriptCore/API/JSClassRef.h \ JavaScriptCore/API/JSContextRef.cpp \ @@ -70,68 +70,65 @@ javascriptcore_sources += \ JavaScriptCore/API/JSWeakObjectMapRefInternal.h \ JavaScriptCore/API/OpaqueJSString.cpp \ JavaScriptCore/API/OpaqueJSString.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/APICast.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSBase.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSContextRef.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSObjectRef.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSRetainPtr.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSStringRef.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSStringRefCF.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSValueRef.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JavaScript.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/JavaScriptCore.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/OpaqueJSString.h \ - JavaScriptCore/ForwardingHeaders/JavaScriptCore/WebKitAvailability.h \ - JavaScriptCore/JavaScriptCorePrefix.h \ - JavaScriptCore/jit/ExecutableAllocator.h \ - JavaScriptCore/jit/JIT.cpp \ - JavaScriptCore/jit/JITOpcodes.cpp \ - JavaScriptCore/jit/JITOpcodes32_64.cpp \ - JavaScriptCore/jit/JITCall.cpp \ - JavaScriptCore/jit/JITCall32_64.cpp \ - JavaScriptCore/jit/JITCode.h \ - JavaScriptCore/jit/JITPropertyAccess.cpp \ - JavaScriptCore/jit/JITPropertyAccess32_64.cpp \ - JavaScriptCore/jit/JITArithmetic.cpp \ - JavaScriptCore/jit/JITArithmetic32_64.cpp \ - JavaScriptCore/jit/ExecutableAllocator.cpp \ - JavaScriptCore/jit/JIT.h \ - JavaScriptCore/jit/JITInlineMethods.h \ - JavaScriptCore/jit/JITStubs.cpp \ - JavaScriptCore/jit/JITStubs.h \ - JavaScriptCore/jit/JITStubCall.h \ - JavaScriptCore/jit/JSInterfaceJIT.h \ - JavaScriptCore/jit/SpecializedThunkJIT.h \ - JavaScriptCore/jit/ThunkGenerators.cpp \ - JavaScriptCore/jit/ThunkGenerators.h \ - JavaScriptCore/bytecode/StructureStubInfo.cpp \ - JavaScriptCore/bytecode/StructureStubInfo.h \ + JavaScriptCore/assembler/AbstractMacroAssembler.h \ + JavaScriptCore/assembler/ARMAssembler.cpp \ + JavaScriptCore/assembler/ARMAssembler.h \ + JavaScriptCore/assembler/AssemblerBuffer.h \ + JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h \ + JavaScriptCore/assembler/CodeLocation.h \ + JavaScriptCore/assembler/LinkBuffer.h \ + JavaScriptCore/assembler/MacroAssemblerARM.cpp \ + JavaScriptCore/assembler/MacroAssemblerARM.h \ + JavaScriptCore/assembler/MacroAssemblerCodeRef.h \ + JavaScriptCore/assembler/MacroAssembler.h \ + JavaScriptCore/assembler/MacroAssemblerX86_64.h \ + JavaScriptCore/assembler/MacroAssemblerX86Common.h \ + JavaScriptCore/assembler/MacroAssemblerX86.h \ + JavaScriptCore/assembler/RepatchBuffer.h \ + JavaScriptCore/assembler/X86Assembler.h \ JavaScriptCore/bytecode/CodeBlock.cpp \ JavaScriptCore/bytecode/CodeBlock.h \ - JavaScriptCore/bytecode/JumpTable.cpp \ - JavaScriptCore/bytecode/JumpTable.h \ JavaScriptCore/bytecode/EvalCodeCache.h \ JavaScriptCore/bytecode/Instruction.h \ - JavaScriptCore/bytecompiler/Label.h \ - JavaScriptCore/interpreter/Interpreter.cpp \ - JavaScriptCore/interpreter/Interpreter.h \ + JavaScriptCore/bytecode/JumpTable.cpp \ + JavaScriptCore/bytecode/JumpTable.h \ JavaScriptCore/bytecode/Opcode.cpp \ JavaScriptCore/bytecode/Opcode.h \ - JavaScriptCore/interpreter/Register.h \ - JavaScriptCore/bytecompiler/RegisterID.h \ JavaScriptCore/bytecode/SamplingTool.cpp \ JavaScriptCore/bytecode/SamplingTool.h \ + JavaScriptCore/bytecode/StructureStubInfo.cpp \ + JavaScriptCore/bytecode/StructureStubInfo.h \ + JavaScriptCore/bytecompiler/BytecodeGenerator.cpp \ + JavaScriptCore/bytecompiler/BytecodeGenerator.h \ + JavaScriptCore/bytecompiler/Label.h \ + JavaScriptCore/bytecompiler/LabelScope.h \ + JavaScriptCore/bytecompiler/NodesCodegen.cpp \ + JavaScriptCore/bytecompiler/RegisterID.h \ JavaScriptCore/config.h \ JavaScriptCore/debugger/DebuggerActivation.cpp \ JavaScriptCore/debugger/DebuggerActivation.h \ JavaScriptCore/debugger/DebuggerCallFrame.cpp \ JavaScriptCore/debugger/DebuggerCallFrame.h \ + JavaScriptCore/debugger/Debugger.cpp \ + JavaScriptCore/debugger/Debugger.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/APICast.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JavaScriptCore.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JavaScript.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSBase.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSContextRef.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSObjectRef.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSRetainPtr.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSStringRefCF.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSStringRef.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSValueRef.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/OpaqueJSString.h \ + JavaScriptCore/ForwardingHeaders/JavaScriptCore/WebKitAvailability.h \ JavaScriptCore/icu/unicode/parseerr.h \ JavaScriptCore/icu/unicode/platform.h \ JavaScriptCore/icu/unicode/putil.h \ JavaScriptCore/icu/unicode/uchar.h \ - JavaScriptCore/icu/unicode/ucnv.h \ JavaScriptCore/icu/unicode/ucnv_err.h \ + JavaScriptCore/icu/unicode/ucnv.h \ JavaScriptCore/icu/unicode/ucol.h \ JavaScriptCore/icu/unicode/uconfig.h \ JavaScriptCore/icu/unicode/uenum.h \ @@ -142,245 +139,45 @@ javascriptcore_sources += \ JavaScriptCore/icu/unicode/urename.h \ JavaScriptCore/icu/unicode/uset.h \ JavaScriptCore/icu/unicode/ustring.h \ - JavaScriptCore/icu/unicode/utf.h \ JavaScriptCore/icu/unicode/utf16.h \ JavaScriptCore/icu/unicode/utf8.h \ + JavaScriptCore/icu/unicode/utf.h \ JavaScriptCore/icu/unicode/utf_old.h \ JavaScriptCore/icu/unicode/utypes.h \ JavaScriptCore/icu/unicode/uversion.h \ - JavaScriptCore/assembler/ARMAssembler.h \ - JavaScriptCore/assembler/ARMAssembler.cpp \ - JavaScriptCore/assembler/X86Assembler.h \ - JavaScriptCore/assembler/AbstractMacroAssembler.h \ - JavaScriptCore/assembler/AssemblerBuffer.h \ - JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h \ - JavaScriptCore/assembler/CodeLocation.h \ - JavaScriptCore/assembler/LinkBuffer.h \ - JavaScriptCore/assembler/MacroAssembler.h \ - JavaScriptCore/assembler/MacroAssemblerARM.h \ - JavaScriptCore/assembler/MacroAssemblerARM.cpp \ - JavaScriptCore/assembler/MacroAssemblerCodeRef.h \ - JavaScriptCore/assembler/MacroAssemblerX86.h \ - JavaScriptCore/assembler/MacroAssemblerX86_64.h \ - JavaScriptCore/assembler/MacroAssemblerX86Common.h \ - JavaScriptCore/assembler/RepatchBuffer.h \ - JavaScriptCore/os-win32/stdbool.h \ - JavaScriptCore/os-win32/stdint.h \ - JavaScriptCore/pcre/pcre.h \ - JavaScriptCore/pcre/pcre_compile.cpp \ - JavaScriptCore/pcre/pcre_exec.cpp \ - JavaScriptCore/pcre/pcre_internal.h \ - JavaScriptCore/pcre/pcre_tables.cpp \ - JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp \ - JavaScriptCore/pcre/pcre_xclass.cpp \ - JavaScriptCore/pcre/ucpinternal.h \ - JavaScriptCore/profiler/CallIdentifier.h \ - JavaScriptCore/profiler/Profile.cpp \ - JavaScriptCore/profiler/Profile.h \ - JavaScriptCore/profiler/ProfileGenerator.cpp \ - JavaScriptCore/profiler/ProfileGenerator.h \ - JavaScriptCore/profiler/ProfileNode.cpp \ - JavaScriptCore/profiler/ProfileNode.h \ - JavaScriptCore/profiler/Profiler.cpp \ - JavaScriptCore/profiler/Profiler.h \ JavaScriptCore/interpreter/CachedCall.h \ + JavaScriptCore/interpreter/CallFrameClosure.h \ JavaScriptCore/interpreter/CallFrame.cpp \ JavaScriptCore/interpreter/CallFrame.h \ - JavaScriptCore/interpreter/CallFrameClosure.h \ - JavaScriptCore/runtime/CachedTranscendentalFunction.h \ - JavaScriptCore/runtime/ExceptionHelpers.cpp \ - JavaScriptCore/runtime/ExceptionHelpers.h \ - JavaScriptCore/runtime/Executable.cpp \ - JavaScriptCore/runtime/Executable.h \ - JavaScriptCore/runtime/InitializeThreading.cpp \ - JavaScriptCore/runtime/InitializeThreading.h \ - JavaScriptCore/runtime/JSActivation.cpp \ - JavaScriptCore/runtime/JSActivation.h \ - JavaScriptCore/runtime/JSByteArray.cpp \ - JavaScriptCore/runtime/JSByteArray.h \ - JavaScriptCore/runtime/JSGlobalData.cpp \ - JavaScriptCore/runtime/JSGlobalData.h \ - JavaScriptCore/runtime/JSNotAnObject.cpp \ - JavaScriptCore/runtime/JSNotAnObject.h \ - JavaScriptCore/runtime/JSONObject.cpp \ - JavaScriptCore/runtime/JSONObject.h \ - JavaScriptCore/runtime/JSPropertyNameIterator.cpp \ - JavaScriptCore/runtime/JSPropertyNameIterator.h \ - JavaScriptCore/runtime/JSStringBuilder.h \ - JavaScriptCore/runtime/JSZombie.h \ - JavaScriptCore/runtime/LiteralParser.cpp \ - JavaScriptCore/runtime/LiteralParser.h \ - JavaScriptCore/runtime/MarkStack.cpp \ - JavaScriptCore/runtime/MarkStack.h \ - JavaScriptCore/runtime/NumericStrings.h \ - JavaScriptCore/runtime/PropertyDescriptor.h \ - JavaScriptCore/runtime/PropertyDescriptor.cpp \ - JavaScriptCore/runtime/SmallStrings.cpp \ - JavaScriptCore/runtime/SmallStrings.h \ - JavaScriptCore/runtime/StringBuilder.h \ - JavaScriptCore/runtime/Structure.cpp \ - JavaScriptCore/runtime/Structure.h \ - JavaScriptCore/runtime/StructureChain.cpp \ - JavaScriptCore/runtime/StructureChain.h \ - JavaScriptCore/runtime/StructureTransitionTable.h \ - JavaScriptCore/runtime/Terminator.h \ - JavaScriptCore/runtime/TimeoutChecker.cpp \ - JavaScriptCore/runtime/TimeoutChecker.h \ - JavaScriptCore/runtime/JSTypeInfo.h \ - JavaScriptCore/runtime/WeakGCMap.h \ - JavaScriptCore/runtime/WeakGCPtr.h \ - JavaScriptCore/wtf/ASCIICType.h \ - JavaScriptCore/wtf/AVLTree.h \ - JavaScriptCore/wtf/AlwaysInline.h \ - JavaScriptCore/wtf/Assertions.cpp \ - JavaScriptCore/wtf/Assertions.h \ - JavaScriptCore/wtf/Atomics.h \ - JavaScriptCore/wtf/ByteArray.cpp \ - JavaScriptCore/wtf/ByteArray.h \ - JavaScriptCore/wtf/CrossThreadRefCounted.h \ - JavaScriptCore/wtf/CurrentTime.cpp \ - JavaScriptCore/wtf/CurrentTime.h \ - JavaScriptCore/wtf/DateMath.cpp \ - JavaScriptCore/wtf/DateMath.h \ - JavaScriptCore/wtf/Deque.h \ - JavaScriptCore/wtf/DisallowCType.h \ - JavaScriptCore/wtf/Forward.h \ - JavaScriptCore/wtf/GetPtr.h \ - JavaScriptCore/wtf/HashCountedSet.h \ - JavaScriptCore/wtf/HashFunctions.h \ - JavaScriptCore/wtf/HashIterators.h \ - JavaScriptCore/wtf/HashMap.h \ - JavaScriptCore/wtf/HashSet.h \ - JavaScriptCore/wtf/HashTable.cpp \ - JavaScriptCore/wtf/HashTable.h \ - JavaScriptCore/wtf/HashTraits.h \ - JavaScriptCore/wtf/ListHashSet.h \ - JavaScriptCore/wtf/ListRefPtr.h \ - JavaScriptCore/wtf/Locker.h \ - JavaScriptCore/wtf/MD5.cpp \ - JavaScriptCore/wtf/MD5.h \ - JavaScriptCore/wtf/MainThread.cpp \ - JavaScriptCore/wtf/MainThread.h \ - JavaScriptCore/wtf/MathExtras.h \ - JavaScriptCore/wtf/MessageQueue.h \ - JavaScriptCore/wtf/Noncopyable.h \ - JavaScriptCore/wtf/NotFound.h \ - JavaScriptCore/wtf/OwnArrayPtr.h \ - JavaScriptCore/wtf/OwnFastMallocPtr.h \ - JavaScriptCore/wtf/OwnPtr.h \ - JavaScriptCore/wtf/OwnPtrCommon.h \ - JavaScriptCore/wtf/PassOwnPtr.h \ - JavaScriptCore/wtf/PassRefPtr.h \ - JavaScriptCore/wtf/Platform.h \ - JavaScriptCore/wtf/PossiblyNull.h \ - JavaScriptCore/wtf/RandomNumber.cpp \ - JavaScriptCore/wtf/RandomNumber.h \ - JavaScriptCore/wtf/RandomNumberSeed.h \ - JavaScriptCore/wtf/RefCounted.h \ - JavaScriptCore/wtf/RefCountedLeakCounter.cpp \ - JavaScriptCore/wtf/RefCountedLeakCounter.h \ - JavaScriptCore/wtf/RefPtr.h \ - JavaScriptCore/wtf/RefPtrHashMap.h \ - JavaScriptCore/wtf/RetainPtr.h \ - JavaScriptCore/wtf/SegmentedVector.h \ - JavaScriptCore/wtf/StaticConstructors.h \ - JavaScriptCore/wtf/StdLibExtras.h \ - JavaScriptCore/wtf/StringExtras.h \ - JavaScriptCore/wtf/StringHashFunctions.h \ - JavaScriptCore/wtf/TCPackedCache.h \ - JavaScriptCore/wtf/TCPageMap.h \ - JavaScriptCore/wtf/TCSpinLock.h \ - JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp \ - JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \ - JavaScriptCore/wtf/Threading.cpp \ - JavaScriptCore/wtf/Threading.h \ - JavaScriptCore/wtf/ThreadingPrimitives.h \ - JavaScriptCore/wtf/ThreadingPthreads.cpp \ - JavaScriptCore/wtf/ThreadSafeShared.h \ - JavaScriptCore/wtf/ThreadSpecific.h \ - JavaScriptCore/wtf/TypeTraits.cpp \ - JavaScriptCore/wtf/TypeTraits.h \ - JavaScriptCore/wtf/UnusedParam.h \ - JavaScriptCore/wtf/ValueCheck.h \ - JavaScriptCore/wtf/Vector.h \ - JavaScriptCore/wtf/VectorTraits.h \ - JavaScriptCore/wtf/WTFThreadData.cpp \ - JavaScriptCore/wtf/WTFThreadData.h \ - JavaScriptCore/wtf/gobject/GOwnPtr.cpp \ - JavaScriptCore/wtf/gobject/GOwnPtr.h \ - JavaScriptCore/wtf/gobject/GRefPtr.cpp \ - JavaScriptCore/wtf/gobject/GRefPtr.h \ - JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \ - JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \ - JavaScriptCore/wtf/text/AtomicString.cpp \ - JavaScriptCore/wtf/text/AtomicString.h \ - JavaScriptCore/wtf/text/AtomicStringImpl.h \ - JavaScriptCore/wtf/text/CString.cpp \ - JavaScriptCore/wtf/text/CString.h \ - JavaScriptCore/wtf/text/StringBuffer.h \ - JavaScriptCore/wtf/text/StringHash.h \ - JavaScriptCore/wtf/text/StringImpl.cpp \ - JavaScriptCore/wtf/text/StringImpl.h \ - JavaScriptCore/wtf/text/StringImplBase.h \ - JavaScriptCore/wtf/text/StringStatics.cpp \ - JavaScriptCore/wtf/text/WTFString.cpp \ - JavaScriptCore/wtf/text/WTFString.h \ - JavaScriptCore/wtf/unicode/Collator.h \ - JavaScriptCore/wtf/unicode/CollatorDefault.cpp \ - JavaScriptCore/wtf/unicode/UTF8.cpp \ - JavaScriptCore/wtf/unicode/UTF8.h \ - JavaScriptCore/wtf/unicode/Unicode.h - -if TARGET_WIN32 -javascriptcore_sources += \ - JavaScriptCore/wtf/ThreadSpecificWin.cpp \ - JavaScriptCore/jit/ExecutableAllocatorWin.cpp \ - JavaScriptCore/runtime/MarkStackWin.cpp -else -javascriptcore_sources += \ - JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \ - JavaScriptCore/runtime/MarkStackPosix.cpp -endif - -# ---- -# icu unicode backend -# ---- -if USE_ICU_UNICODE -javascriptcore_sources += \ - JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp \ - JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h -endif # USE_ICU_UNICODE - -# ---- -# glib unicode backend -# ---- -if USE_GLIB_UNICODE -javascriptcore_sources += \ - JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \ - JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp \ - JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h -endif - -javascriptcore_sources += \ - JavaScriptCore/wtf/VMTags.h \ - JavaScriptCore/yarr/RegexCompiler.cpp \ - JavaScriptCore/yarr/RegexCompiler.h \ - JavaScriptCore/yarr/RegexInterpreter.cpp \ - JavaScriptCore/yarr/RegexInterpreter.h \ - JavaScriptCore/yarr/RegexJIT.cpp \ - JavaScriptCore/yarr/RegexJIT.h \ - JavaScriptCore/yarr/RegexParser.h \ - JavaScriptCore/yarr/RegexPattern.h - -javascriptcore_sources += \ + JavaScriptCore/interpreter/Interpreter.cpp \ + JavaScriptCore/interpreter/Interpreter.h \ JavaScriptCore/interpreter/RegisterFile.cpp \ JavaScriptCore/interpreter/RegisterFile.h \ - JavaScriptCore/bytecompiler/BytecodeGenerator.cpp \ - JavaScriptCore/bytecompiler/BytecodeGenerator.h \ - JavaScriptCore/bytecompiler/NodesCodegen.cpp \ - JavaScriptCore/bytecompiler/LabelScope.h \ - JavaScriptCore/debugger/Debugger.cpp \ - JavaScriptCore/debugger/Debugger.h \ + JavaScriptCore/interpreter/Register.h \ + JavaScriptCore/JavaScriptCorePrefix.h \ + JavaScriptCore/jit/ExecutableAllocator.cpp \ + JavaScriptCore/jit/ExecutableAllocator.h \ + JavaScriptCore/jit/JITArithmetic32_64.cpp \ + JavaScriptCore/jit/JITArithmetic.cpp \ + JavaScriptCore/jit/JITCall32_64.cpp \ + JavaScriptCore/jit/JITCall.cpp \ + JavaScriptCore/jit/JITCode.h \ + JavaScriptCore/jit/JIT.cpp \ + JavaScriptCore/jit/JIT.h \ + JavaScriptCore/jit/JITInlineMethods.h \ + JavaScriptCore/jit/JITOpcodes32_64.cpp \ + JavaScriptCore/jit/JITOpcodes.cpp \ + JavaScriptCore/jit/JITPropertyAccess32_64.cpp \ + JavaScriptCore/jit/JITPropertyAccess.cpp \ + JavaScriptCore/jit/JITStubCall.h \ + JavaScriptCore/jit/JITStubs.cpp \ + JavaScriptCore/jit/JITStubs.h \ + JavaScriptCore/jit/JSInterfaceJIT.h \ + JavaScriptCore/jit/SpecializedThunkJIT.h \ + JavaScriptCore/jit/ThunkGenerators.cpp \ + JavaScriptCore/jit/ThunkGenerators.h \ + JavaScriptCore/os-win32/stdbool.h \ + JavaScriptCore/os-win32/stdint.h \ JavaScriptCore/parser/ASTBuilder.h \ JavaScriptCore/parser/JSParser.cpp \ JavaScriptCore/parser/JSParser.h \ @@ -390,14 +187,31 @@ javascriptcore_sources += \ JavaScriptCore/parser/NodeInfo.h \ JavaScriptCore/parser/Nodes.cpp \ JavaScriptCore/parser/Nodes.h \ - JavaScriptCore/parser/Parser.cpp \ - JavaScriptCore/parser/Parser.h \ JavaScriptCore/parser/ParserArena.cpp \ JavaScriptCore/parser/ParserArena.h \ + JavaScriptCore/parser/Parser.cpp \ + JavaScriptCore/parser/Parser.h \ JavaScriptCore/parser/ResultType.h \ JavaScriptCore/parser/SourceCode.h \ JavaScriptCore/parser/SourceProvider.h \ JavaScriptCore/parser/SyntaxChecker.h \ + JavaScriptCore/pcre/pcre_compile.cpp \ + JavaScriptCore/pcre/pcre_exec.cpp \ + JavaScriptCore/pcre/pcre.h \ + JavaScriptCore/pcre/pcre_internal.h \ + JavaScriptCore/pcre/pcre_tables.cpp \ + JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp \ + JavaScriptCore/pcre/pcre_xclass.cpp \ + JavaScriptCore/pcre/ucpinternal.h \ + JavaScriptCore/profiler/CallIdentifier.h \ + JavaScriptCore/profiler/Profile.cpp \ + JavaScriptCore/profiler/ProfileGenerator.cpp \ + JavaScriptCore/profiler/ProfileGenerator.h \ + JavaScriptCore/profiler/Profile.h \ + JavaScriptCore/profiler/ProfileNode.cpp \ + JavaScriptCore/profiler/ProfileNode.h \ + JavaScriptCore/profiler/Profiler.cpp \ + JavaScriptCore/profiler/Profiler.h \ JavaScriptCore/runtime/ArgList.cpp \ JavaScriptCore/runtime/ArgList.h \ JavaScriptCore/runtime/Arguments.cpp \ @@ -413,6 +227,7 @@ javascriptcore_sources += \ JavaScriptCore/runtime/BooleanObject.h \ JavaScriptCore/runtime/BooleanPrototype.cpp \ JavaScriptCore/runtime/BooleanPrototype.h \ + JavaScriptCore/runtime/CachedTranscendentalFunction.h \ JavaScriptCore/runtime/CallData.cpp \ JavaScriptCore/runtime/CallData.h \ JavaScriptCore/runtime/ClassInfo.h \ @@ -421,6 +236,7 @@ javascriptcore_sources += \ JavaScriptCore/runtime/CollectorHeapIterator.h \ JavaScriptCore/runtime/CommonIdentifiers.cpp \ JavaScriptCore/runtime/CommonIdentifiers.h \ + JavaScriptCore/runtime/Completion.cpp \ JavaScriptCore/runtime/Completion.h \ JavaScriptCore/runtime/ConstructData.cpp \ JavaScriptCore/runtime/ConstructData.h \ @@ -428,19 +244,23 @@ javascriptcore_sources += \ JavaScriptCore/runtime/DateConstructor.h \ JavaScriptCore/runtime/DateConversion.cpp \ JavaScriptCore/runtime/DateConversion.h \ + JavaScriptCore/runtime/DateInstanceCache.h \ JavaScriptCore/runtime/DateInstance.cpp \ JavaScriptCore/runtime/DateInstance.h \ - JavaScriptCore/runtime/DateInstanceCache.h \ JavaScriptCore/runtime/DatePrototype.cpp \ JavaScriptCore/runtime/DatePrototype.h \ - JavaScriptCore/runtime/Error.cpp \ - JavaScriptCore/runtime/Error.h \ JavaScriptCore/runtime/ErrorConstructor.cpp \ JavaScriptCore/runtime/ErrorConstructor.h \ + JavaScriptCore/runtime/Error.cpp \ + JavaScriptCore/runtime/Error.h \ JavaScriptCore/runtime/ErrorInstance.cpp \ JavaScriptCore/runtime/ErrorInstance.h \ JavaScriptCore/runtime/ErrorPrototype.cpp \ JavaScriptCore/runtime/ErrorPrototype.h \ + JavaScriptCore/runtime/ExceptionHelpers.cpp \ + JavaScriptCore/runtime/ExceptionHelpers.h \ + JavaScriptCore/runtime/Executable.cpp \ + JavaScriptCore/runtime/Executable.h \ JavaScriptCore/runtime/FunctionConstructor.cpp \ JavaScriptCore/runtime/FunctionConstructor.h \ JavaScriptCore/runtime/FunctionPrototype.cpp \ @@ -451,44 +271,64 @@ javascriptcore_sources += \ JavaScriptCore/runtime/GlobalEvalFunction.h \ JavaScriptCore/runtime/Identifier.cpp \ JavaScriptCore/runtime/Identifier.h \ + JavaScriptCore/runtime/InitializeThreading.cpp \ + JavaScriptCore/runtime/InitializeThreading.h \ JavaScriptCore/runtime/InternalFunction.cpp \ JavaScriptCore/runtime/InternalFunction.h \ - JavaScriptCore/runtime/Completion.cpp \ - JavaScriptCore/runtime/JSArray.cpp \ - JavaScriptCore/runtime/JSArray.h \ + JavaScriptCore/runtime/JSActivation.cpp \ + JavaScriptCore/runtime/JSActivation.h \ JavaScriptCore/runtime/JSAPIValueWrapper.cpp \ JavaScriptCore/runtime/JSAPIValueWrapper.h \ + JavaScriptCore/runtime/JSArray.cpp \ + JavaScriptCore/runtime/JSArray.h \ + JavaScriptCore/runtime/JSByteArray.cpp \ + JavaScriptCore/runtime/JSByteArray.h \ JavaScriptCore/runtime/JSCell.cpp \ JavaScriptCore/runtime/JSCell.h \ JavaScriptCore/runtime/JSFunction.cpp \ JavaScriptCore/runtime/JSFunction.h \ + JavaScriptCore/runtime/JSGlobalData.cpp \ + JavaScriptCore/runtime/JSGlobalData.h \ JavaScriptCore/runtime/JSGlobalObject.cpp \ - JavaScriptCore/runtime/JSGlobalObject.h \ JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp \ JavaScriptCore/runtime/JSGlobalObjectFunctions.h \ + JavaScriptCore/runtime/JSGlobalObject.h \ JavaScriptCore/runtime/JSImmediate.cpp \ JavaScriptCore/runtime/JSImmediate.h \ JavaScriptCore/runtime/JSLock.cpp \ JavaScriptCore/runtime/JSLock.h \ + JavaScriptCore/runtime/JSNotAnObject.cpp \ + JavaScriptCore/runtime/JSNotAnObject.h \ JavaScriptCore/runtime/JSNumberCell.cpp \ JavaScriptCore/runtime/JSNumberCell.h \ JavaScriptCore/runtime/JSObject.cpp \ + JavaScriptCore/runtime/JSObject.h \ JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp \ JavaScriptCore/runtime/JSObjectWithGlobalObject.h \ - JavaScriptCore/runtime/JSObject.h \ + JavaScriptCore/runtime/JSONObject.cpp \ + JavaScriptCore/runtime/JSONObject.h \ + JavaScriptCore/runtime/JSPropertyNameIterator.cpp \ + JavaScriptCore/runtime/JSPropertyNameIterator.h \ JavaScriptCore/runtime/JSStaticScopeObject.cpp \ JavaScriptCore/runtime/JSStaticScopeObject.h \ + JavaScriptCore/runtime/JSStringBuilder.h \ JavaScriptCore/runtime/JSString.cpp \ JavaScriptCore/runtime/JSString.h \ JavaScriptCore/runtime/JSType.h \ + JavaScriptCore/runtime/JSTypeInfo.h \ JavaScriptCore/runtime/JSValue.cpp \ JavaScriptCore/runtime/JSValue.h \ JavaScriptCore/runtime/JSVariableObject.cpp \ JavaScriptCore/runtime/JSVariableObject.h \ JavaScriptCore/runtime/JSWrapperObject.cpp \ JavaScriptCore/runtime/JSWrapperObject.h \ + JavaScriptCore/runtime/JSZombie.h \ + JavaScriptCore/runtime/LiteralParser.cpp \ + JavaScriptCore/runtime/LiteralParser.h \ JavaScriptCore/runtime/Lookup.cpp \ JavaScriptCore/runtime/Lookup.h \ + JavaScriptCore/runtime/MarkStack.cpp \ + JavaScriptCore/runtime/MarkStack.h \ JavaScriptCore/runtime/MathObject.cpp \ JavaScriptCore/runtime/MathObject.h \ JavaScriptCore/runtime/NativeErrorConstructor.cpp \ @@ -502,12 +342,15 @@ javascriptcore_sources += \ JavaScriptCore/runtime/NumberObject.h \ JavaScriptCore/runtime/NumberPrototype.cpp \ JavaScriptCore/runtime/NumberPrototype.h \ + JavaScriptCore/runtime/NumericStrings.h \ JavaScriptCore/runtime/ObjectConstructor.cpp \ JavaScriptCore/runtime/ObjectConstructor.h \ JavaScriptCore/runtime/ObjectPrototype.cpp \ JavaScriptCore/runtime/ObjectPrototype.h \ JavaScriptCore/runtime/Operations.cpp \ JavaScriptCore/runtime/Operations.h \ + JavaScriptCore/runtime/PropertyDescriptor.cpp \ + JavaScriptCore/runtime/PropertyDescriptor.h \ JavaScriptCore/runtime/PropertyMapHashTable.h \ JavaScriptCore/runtime/PropertyNameArray.cpp \ JavaScriptCore/runtime/PropertyNameArray.h \ @@ -517,12 +360,12 @@ javascriptcore_sources += \ JavaScriptCore/runtime/PrototypeFunction.cpp \ JavaScriptCore/runtime/PrototypeFunction.h \ JavaScriptCore/runtime/PutPropertySlot.h \ - JavaScriptCore/runtime/RegExp.cpp \ - JavaScriptCore/runtime/RegExp.h \ JavaScriptCore/runtime/RegExpCache.cpp \ JavaScriptCore/runtime/RegExpCache.h \ JavaScriptCore/runtime/RegExpConstructor.cpp \ JavaScriptCore/runtime/RegExpConstructor.h \ + JavaScriptCore/runtime/RegExp.cpp \ + JavaScriptCore/runtime/RegExp.h \ JavaScriptCore/runtime/RegExpKey.h \ JavaScriptCore/runtime/RegExpMatchesArray.h \ JavaScriptCore/runtime/RegExpObject.cpp \ @@ -534,6 +377,9 @@ javascriptcore_sources += \ JavaScriptCore/runtime/ScopeChain.cpp \ JavaScriptCore/runtime/ScopeChain.h \ JavaScriptCore/runtime/ScopeChainMark.h \ + JavaScriptCore/runtime/SmallStrings.cpp \ + JavaScriptCore/runtime/SmallStrings.h \ + JavaScriptCore/runtime/StringBuilder.h \ JavaScriptCore/runtime/StringConstructor.cpp \ JavaScriptCore/runtime/StringConstructor.h \ JavaScriptCore/runtime/StringObject.cpp \ @@ -541,34 +387,172 @@ javascriptcore_sources += \ JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h \ JavaScriptCore/runtime/StringPrototype.cpp \ JavaScriptCore/runtime/StringPrototype.h \ + JavaScriptCore/runtime/StructureChain.cpp \ + JavaScriptCore/runtime/StructureChain.h \ + JavaScriptCore/runtime/Structure.cpp \ + JavaScriptCore/runtime/Structure.h \ + JavaScriptCore/runtime/StructureTransitionTable.h \ JavaScriptCore/runtime/SymbolTable.h \ + JavaScriptCore/runtime/Terminator.h \ + JavaScriptCore/runtime/TimeoutChecker.cpp \ + JavaScriptCore/runtime/TimeoutChecker.h \ JavaScriptCore/runtime/Tracing.h \ JavaScriptCore/runtime/UString.cpp \ JavaScriptCore/runtime/UString.h \ JavaScriptCore/runtime/UStringImpl.h \ + JavaScriptCore/runtime/WeakGCMap.h \ + JavaScriptCore/runtime/WeakGCPtr.h \ JavaScriptCore/runtime/WeakRandom.h \ + JavaScriptCore/wtf/AlwaysInline.h \ + JavaScriptCore/wtf/ASCIICType.h \ + JavaScriptCore/wtf/Assertions.cpp \ + JavaScriptCore/wtf/Assertions.h \ + JavaScriptCore/wtf/Atomics.h \ + JavaScriptCore/wtf/AVLTree.h \ + JavaScriptCore/wtf/ByteArray.cpp \ + JavaScriptCore/wtf/ByteArray.h \ + JavaScriptCore/wtf/CrossThreadRefCounted.h \ + JavaScriptCore/wtf/CurrentTime.cpp \ + JavaScriptCore/wtf/CurrentTime.h \ + JavaScriptCore/wtf/DateMath.cpp \ + JavaScriptCore/wtf/DateMath.h \ + JavaScriptCore/wtf/Deque.h \ + JavaScriptCore/wtf/DisallowCType.h \ + JavaScriptCore/wtf/dtoa.cpp \ + JavaScriptCore/wtf/dtoa.h \ JavaScriptCore/wtf/FastAllocBase.h \ JavaScriptCore/wtf/FastMalloc.cpp \ JavaScriptCore/wtf/FastMalloc.h \ + JavaScriptCore/wtf/Forward.h \ + JavaScriptCore/wtf/GetPtr.h \ + JavaScriptCore/wtf/gobject/GOwnPtr.cpp \ + JavaScriptCore/wtf/gobject/GOwnPtr.h \ + JavaScriptCore/wtf/gobject/GRefPtr.cpp \ + JavaScriptCore/wtf/gobject/GRefPtr.h \ + JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \ + JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \ + JavaScriptCore/wtf/HashCountedSet.h \ + JavaScriptCore/wtf/HashFunctions.h \ + JavaScriptCore/wtf/HashIterators.h \ + JavaScriptCore/wtf/HashMap.h \ + JavaScriptCore/wtf/HashSet.h \ + JavaScriptCore/wtf/HashTable.cpp \ + JavaScriptCore/wtf/HashTable.h \ + JavaScriptCore/wtf/HashTraits.h \ + JavaScriptCore/wtf/ListHashSet.h \ + JavaScriptCore/wtf/ListRefPtr.h \ + JavaScriptCore/wtf/Locker.h \ + JavaScriptCore/wtf/MainThread.cpp \ + JavaScriptCore/wtf/MainThread.h \ JavaScriptCore/wtf/MallocZoneSupport.h \ + JavaScriptCore/wtf/MathExtras.h \ + JavaScriptCore/wtf/MD5.cpp \ + JavaScriptCore/wtf/MD5.h \ + JavaScriptCore/wtf/MessageQueue.h \ + JavaScriptCore/wtf/Noncopyable.h \ + JavaScriptCore/wtf/NotFound.h \ + JavaScriptCore/wtf/OwnArrayPtr.h \ + JavaScriptCore/wtf/OwnFastMallocPtr.h \ + JavaScriptCore/wtf/OwnPtrCommon.h \ + JavaScriptCore/wtf/OwnPtr.h \ + JavaScriptCore/wtf/PassOwnPtr.h \ + JavaScriptCore/wtf/PassRefPtr.h \ + JavaScriptCore/wtf/Platform.h \ + JavaScriptCore/wtf/PossiblyNull.h \ + JavaScriptCore/wtf/RandomNumber.cpp \ + JavaScriptCore/wtf/RandomNumber.h \ + JavaScriptCore/wtf/RandomNumberSeed.h \ + JavaScriptCore/wtf/RefCounted.h \ + JavaScriptCore/wtf/RefCountedLeakCounter.cpp \ + JavaScriptCore/wtf/RefCountedLeakCounter.h \ + JavaScriptCore/wtf/RefPtr.h \ + JavaScriptCore/wtf/RefPtrHashMap.h \ + JavaScriptCore/wtf/RetainPtr.h \ + JavaScriptCore/wtf/SegmentedVector.h \ + JavaScriptCore/wtf/StaticConstructors.h \ + JavaScriptCore/wtf/StdLibExtras.h \ + JavaScriptCore/wtf/StringExtras.h \ + JavaScriptCore/wtf/StringHashFunctions.h \ + JavaScriptCore/wtf/TCPackedCache.h \ + JavaScriptCore/wtf/TCPageMap.h \ + JavaScriptCore/wtf/TCSpinLock.h \ JavaScriptCore/wtf/TCSystemAlloc.cpp \ JavaScriptCore/wtf/TCSystemAlloc.h \ - JavaScriptCore/wtf/dtoa.cpp \ - JavaScriptCore/wtf/dtoa.h + JavaScriptCore/wtf/text/AtomicString.cpp \ + JavaScriptCore/wtf/text/AtomicString.h \ + JavaScriptCore/wtf/text/AtomicStringImpl.h \ + JavaScriptCore/wtf/text/CString.cpp \ + JavaScriptCore/wtf/text/CString.h \ + JavaScriptCore/wtf/text/StringBuffer.h \ + JavaScriptCore/wtf/text/StringHash.h \ + JavaScriptCore/wtf/text/StringImplBase.h \ + JavaScriptCore/wtf/text/StringImpl.cpp \ + JavaScriptCore/wtf/text/StringImpl.h \ + JavaScriptCore/wtf/text/StringStatics.cpp \ + JavaScriptCore/wtf/text/WTFString.cpp \ + JavaScriptCore/wtf/text/WTFString.h \ + JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp \ + JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \ + JavaScriptCore/wtf/Threading.cpp \ + JavaScriptCore/wtf/Threading.h \ + JavaScriptCore/wtf/ThreadingPrimitives.h \ + JavaScriptCore/wtf/ThreadingPthreads.cpp \ + JavaScriptCore/wtf/ThreadSafeShared.h \ + JavaScriptCore/wtf/ThreadSpecific.h \ + JavaScriptCore/wtf/TypeTraits.cpp \ + JavaScriptCore/wtf/TypeTraits.h \ + JavaScriptCore/wtf/unicode/CollatorDefault.cpp \ + JavaScriptCore/wtf/unicode/Collator.h \ + JavaScriptCore/wtf/unicode/Unicode.h \ + JavaScriptCore/wtf/unicode/UTF8.cpp \ + JavaScriptCore/wtf/unicode/UTF8.h \ + JavaScriptCore/wtf/UnusedParam.h \ + JavaScriptCore/wtf/ValueCheck.h \ + JavaScriptCore/wtf/Vector.h \ + JavaScriptCore/wtf/VectorTraits.h \ + JavaScriptCore/wtf/VMTags.h \ + JavaScriptCore/wtf/WTFThreadData.cpp \ + JavaScriptCore/wtf/WTFThreadData.h \ + JavaScriptCore/yarr/RegexCompiler.cpp \ + JavaScriptCore/yarr/RegexCompiler.h \ + JavaScriptCore/yarr/RegexInterpreter.cpp \ + JavaScriptCore/yarr/RegexInterpreter.h \ + JavaScriptCore/yarr/RegexJIT.cpp \ + JavaScriptCore/yarr/RegexJIT.h \ + JavaScriptCore/yarr/RegexParser.h \ + JavaScriptCore/yarr/RegexPattern.h -javascriptcore_built_sources += \ - DerivedSources/Grammar.cpp \ - DerivedSources/Grammar.h +if TARGET_WIN32 +javascriptcore_sources += \ + JavaScriptCore/wtf/ThreadSpecificWin.cpp \ + JavaScriptCore/jit/ExecutableAllocatorWin.cpp \ + JavaScriptCore/runtime/MarkStackWin.cpp +else +javascriptcore_sources += \ + JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \ + JavaScriptCore/runtime/MarkStackPosix.cpp +endif -DerivedSources/Grammar.h: DerivedSources/Grammar.cpp; +# ---- +# icu unicode backend +# ---- +if USE_ICU_UNICODE +javascriptcore_sources += \ + JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp \ + JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h +endif # USE_ICU_UNICODE -DerivedSources/Grammar.cpp: $(srcdir)/JavaScriptCore/parser/Grammar.y - $(BISON) -d -p jscyy $(srcdir)/JavaScriptCore/parser/Grammar.y -o $@ > bison_out.txt 2>&1 - $(PERL) -p -e 'END { if ($$conflict) { unlink "Grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt - cat $(GENSOURCES)/Grammar.hpp > $(GENSOURCES)/Grammar.h - rm -f $(GENSOURCES)/Grammar.hpp bison_out.txt +# ---- +# glib unicode backend +# ---- +if USE_GLIB_UNICODE +javascriptcore_sources += \ + JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \ + JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp \ + JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h +endif -DerivedSources/Lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/parser/Keywords.table +JavaScriptCore/Lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/parser/Keywords.table $(PERL) $^ > $@ JavaScriptCore/%.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/%.cpp @@ -581,9 +565,10 @@ JavaScriptCore/pcre/chartables.c: $(srcdir)/JavaScriptCore/pcre/dftables $(PERL) $^ $@ bin_PROGRAMS += \ - Programs/jsc + Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@ noinst_PROGRAMS += \ + Programs/jsc \ Programs/minidom # minidom @@ -618,6 +603,11 @@ Programs_minidom_LDFLAGS = \ -no-fast-install # jsc +Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@: Programs/jsc + $(AM_V_GEN)cp -f Programs/jsc Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@ +Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_LDADD = +Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_SOURCES = + Programs_jsc_SOURCES = \ JavaScriptCore/jsc.cpp @@ -648,7 +638,6 @@ javascriptcore_dist += \ JavaScriptCore/pcre/AUTHORS \ JavaScriptCore/pcre/dftables \ JavaScriptCore/pcre/ucptable.cpp \ - JavaScriptCore/parser/Grammar.y \ JavaScriptCore/parser/Keywords.table # Clean rules for JavaScriptCore @@ -663,4 +652,5 @@ CLEANFILES += \ JavaScriptCore/runtime/StringPrototype.lut.h \ JavaScriptCore/pcre/chartables.c \ Programs/jsc \ + Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@ \ Programs/minidom diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro index 8ee4f09..84ce83c 100644 --- a/JavaScriptCore/JavaScriptCore.pro +++ b/JavaScriptCore/JavaScriptCore.pro @@ -235,8 +235,6 @@ SOURCES += \ yarr/RegexJIT.cpp # Generated files, simply list them for JavaScriptCore -SOURCES += \ - $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp !contains(DEFINES, USE_SYSTEM_MALLOC) { SOURCES += wtf/TCSystemAlloc.cpp diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index 8117f78..dbddfe0 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -1881,78 +1881,6 @@ >
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.cpp"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGOInstrument|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGOOptimize|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_All|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.h"
- >
- </File>
- <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\lexer.lut.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index bc58f5d..2dd4abd 100644 --- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -145,7 +145,6 @@ 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; }; 1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; }; 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 148F21A3107EC5310042EC2C /* Grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB3F4809D11B2400F49DEB /* Grammar.cpp */; }; 148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */; }; 148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8650255597D01FF60F7 /* Lexer.cpp */; }; 148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A86D0255597D01FF60F7 /* Nodes.cpp */; }; @@ -330,6 +329,7 @@ A7D649AA1015224E009B2E1B /* PossiblyNull.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D649A91015224E009B2E1B /* PossiblyNull.h */; settings = {ATTRIBUTES = (Private, ); }; }; A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E2EA690FB460CF00601F06 /* LiteralParser.h */; }; A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */; }; + A7F19ECE11DD490900931E70 /* FixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F19ECD11DD490900931E70 /* FixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; }; A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; }; A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; }; A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; }; @@ -350,7 +350,7 @@ BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* ArrayPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */ = {isa = PBXBuildFile; fileRef = 938C4F690CA06BC700D9310A /* ASCIICType.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C3EA0E16F5CD00B34460 /* Assertions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E217B708E7EECC0023E5F6 /* Assertions.h */; settings = {ATTRIBUTES = (Private, ); }; }; - BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A596370DE3E1C300C17E37 /* AVLTree.h */; }; + BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A596370DE3E1C300C17E37 /* AVLTree.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 704FD35305697E6D003DBED9 /* BooleanObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */ = {isa = PBXBuildFile; fileRef = 145C507F0D9DF63B0088F6B9 /* CallData.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C3F00E16F5CD00B34460 /* Collator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A862AA0D7EBB7D001EC6AA /* Collator.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -476,7 +476,6 @@ BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5290E16FCC200B34460 /* MathObject.lut.h */; }; BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */; }; BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* Lexer.lut.h */; }; - BC18C5300E16FCEB00B34460 /* Grammar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52F0E16FCEB00B34460 /* Grammar.h */; }; BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; }; BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */; }; BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -758,7 +757,6 @@ 65EA4C9A092AF9E20093D800 /* JSLock.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JSLock.h; sourceTree = "<group>"; tabWidth = 8; }; 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; }; 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; }; - 65FB3F4809D11B2400F49DEB /* Grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Grammar.cpp; sourceTree = "<group>"; }; 704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; }; 7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeChainMark.h; sourceTree = "<group>"; }; 7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; }; @@ -843,7 +841,6 @@ 932F5BE10822A1C700736975 /* jsc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jsc; sourceTree = BUILT_PRODUCTS_DIR; }; 93303FE80E6A72B500786E6A /* SmallStrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmallStrings.cpp; sourceTree = "<group>"; }; 93303FEA0E6A72C000786E6A /* SmallStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallStrings.h; sourceTree = "<group>"; }; - 933A3499038AE7C6008635CE /* Grammar.y */ = {isa = PBXFileReference; explicitFileType = sourcecode.yacc; fileEncoding = 4; indentWidth = 4; path = Grammar.y; sourceTree = "<group>"; tabWidth = 8; }; 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; }; 935AF46909E9D9DB00ACD1D8 /* Forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Forward.h; sourceTree = "<group>"; }; @@ -938,6 +935,7 @@ A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralParser.cpp; sourceTree = "<group>"; }; A7E42C180E3938830065A544 /* JSStaticScopeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStaticScopeObject.h; sourceTree = "<group>"; }; A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStaticScopeObject.cpp; sourceTree = "<group>"; }; + A7F19ECD11DD490900931E70 /* FixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FixedArray.h; sourceTree = "<group>"; }; A7F8690E0F9584A100558697 /* CachedCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedCall.h; sourceTree = "<group>"; }; A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameClosure.h; sourceTree = "<group>"; }; A7F9935D0FD7325100A0B2D0 /* JSONObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONObject.h; sourceTree = "<group>"; }; @@ -979,7 +977,6 @@ BC18C5290E16FCC200B34460 /* MathObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathObject.lut.h; sourceTree = "<group>"; }; BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObject.lut.h; sourceTree = "<group>"; }; BC18C52D0E16FCE100B34460 /* Lexer.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.lut.h; sourceTree = "<group>"; }; - BC18C52F0E16FCEB00B34460 /* Grammar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Grammar.h; sourceTree = "<group>"; }; BC22A3980E16E14800AF21C8 /* JSObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObject.cpp; sourceTree = "<group>"; }; BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; }; BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVariableObject.cpp; sourceTree = "<group>"; }; @@ -1381,8 +1378,6 @@ BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */, 65B174BE09D1000200820339 /* chartables.c */, BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */, - 65FB3F4809D11B2400F49DEB /* Grammar.cpp */, - BC18C52F0E16FCEB00B34460 /* Grammar.h */, BC87CDB810712ACA000614CF /* JSONObject.lut.h */, BC18C52D0E16FCE100B34460 /* Lexer.lut.h */, BC18C5290E16FCC200B34460 /* MathObject.lut.h */, @@ -1491,6 +1486,7 @@ 96DD73780F9DA3100027FBCC /* VMTags.h */, 86D08D5111793613006E5ED0 /* WTFThreadData.cpp */, 86D08D5211793613006E5ED0 /* WTFThreadData.h */, + A7F19ECD11DD490900931E70 /* FixedArray.h */, ); path = wtf; sourceTree = "<group>"; @@ -1531,7 +1527,6 @@ isa = PBXGroup; children = ( A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */, - 933A3499038AE7C6008635CE /* Grammar.y */, A7A7EE7511B98B8D0065A14F /* JSParser.cpp */, A7A7EE7611B98B8D0065A14F /* JSParser.h */, 93F1981A08245AAE001E9ABC /* Keywords.table */, @@ -1967,7 +1962,6 @@ BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */, BC18C4060E16F5CD00B34460 /* GetPtr.h in Headers */, BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */, - BC18C5300E16FCEB00B34460 /* Grammar.h in Headers */, BC18C4080E16F5CD00B34460 /* HashCountedSet.h in Headers */, BC18C4090E16F5CD00B34460 /* HashFunctions.h in Headers */, BC18C40A0E16F5CD00B34460 /* HashIterators.h in Headers */, @@ -2192,6 +2186,7 @@ A784A26111D16622005776AC /* ASTBuilder.h in Headers */, A784A26311D16622005776AC /* JSParser.h in Headers */, A784A26411D16622005776AC /* SyntaxChecker.h in Headers */, + A7F19ECE11DD490900931E70 /* FixedArray.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2505,7 +2500,6 @@ 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */, 14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */, 147F39CD107EC37600427A48 /* GlobalEvalFunction.cpp in Sources */, - 148F21A3107EC5310042EC2C /* Grammar.cpp in Sources */, 65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */, 147F39CE107EC37600427A48 /* Identifier.cpp in Sources */, E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */, diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h index f910d15..48eef53 100644 --- a/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/JavaScriptCore/assembler/ARMv7Assembler.h @@ -56,107 +56,122 @@ namespace ARMRegisters { r15, pc = r15, } RegisterID; - // s0 == d0 == q0 - // s4 == d2 == q1 - // etc typedef enum { - s0 = 0, - s1 = 1, - s2 = 2, - s3 = 3, - s4 = 4, - s5 = 5, - s6 = 6, - s7 = 7, - s8 = 8, - s9 = 9, - s10 = 10, - s11 = 11, - s12 = 12, - s13 = 13, - s14 = 14, - s15 = 15, - s16 = 16, - s17 = 17, - s18 = 18, - s19 = 19, - s20 = 20, - s21 = 21, - s22 = 22, - s23 = 23, - s24 = 24, - s25 = 25, - s26 = 26, - s27 = 27, - s28 = 28, - s29 = 29, - s30 = 30, - s31 = 31, - d0 = 0 << 1, - d1 = 1 << 1, - d2 = 2 << 1, - d3 = 3 << 1, - d4 = 4 << 1, - d5 = 5 << 1, - d6 = 6 << 1, - d7 = 7 << 1, - d8 = 8 << 1, - d9 = 9 << 1, - d10 = 10 << 1, - d11 = 11 << 1, - d12 = 12 << 1, - d13 = 13 << 1, - d14 = 14 << 1, - d15 = 15 << 1, - d16 = 16 << 1, - d17 = 17 << 1, - d18 = 18 << 1, - d19 = 19 << 1, - d20 = 20 << 1, - d21 = 21 << 1, - d22 = 22 << 1, - d23 = 23 << 1, - d24 = 24 << 1, - d25 = 25 << 1, - d26 = 26 << 1, - d27 = 27 << 1, - d28 = 28 << 1, - d29 = 29 << 1, - d30 = 30 << 1, - d31 = 31 << 1, - q0 = 0 << 2, - q1 = 1 << 2, - q2 = 2 << 2, - q3 = 3 << 2, - q4 = 4 << 2, - q5 = 5 << 2, - q6 = 6 << 2, - q7 = 7 << 2, - q8 = 8 << 2, - q9 = 9 << 2, - q10 = 10 << 2, - q11 = 11 << 2, - q12 = 12 << 2, - q13 = 13 << 2, - q14 = 14 << 2, - q15 = 15 << 2, - q16 = 16 << 2, - q17 = 17 << 2, - q18 = 18 << 2, - q19 = 19 << 2, - q20 = 20 << 2, - q21 = 21 << 2, - q22 = 22 << 2, - q23 = 23 << 2, - q24 = 24 << 2, - q25 = 25 << 2, - q26 = 26 << 2, - q27 = 27 << 2, - q28 = 28 << 2, - q29 = 29 << 2, - q30 = 30 << 2, - q31 = 31 << 2, - } FPRegisterID; + s0, + s1, + s2, + s3, + s4, + s5, + s6, + s7, + s8, + s9, + s10, + s11, + s12, + s13, + s14, + s15, + s16, + s17, + s18, + s19, + s20, + s21, + s22, + s23, + s24, + s25, + s26, + s27, + s28, + s29, + s30, + s31, + } FPSingleRegisterID; + + typedef enum { + d0, + d1, + d2, + d3, + d4, + d5, + d6, + d7, + d8, + d9, + d10, + d11, + d12, + d13, + d14, + d15, + d16, + d17, + d18, + d19, + d20, + d21, + d22, + d23, + d24, + d25, + d26, + d27, + d28, + d29, + d30, + d31, + } FPDoubleRegisterID; + + typedef enum { + q0, + q1, + q2, + q3, + q4, + q5, + q6, + q7, + q8, + q9, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + } FPQuadRegisterID; + + inline FPSingleRegisterID asSingle(FPDoubleRegisterID reg) + { + ASSERT(reg < d16); + return (FPSingleRegisterID)(reg << 1); + } + + inline FPDoubleRegisterID asDouble(FPSingleRegisterID reg) + { + ASSERT(!(reg & 1)); + return (FPDoubleRegisterID)(reg >> 1); + } } class ARMv7Assembler; @@ -354,6 +369,39 @@ private: ThumbImmediateValue m_value; }; +class VFPImmediate { +public: + VFPImmediate(double d) + : m_value(-1) + { + union { + uint64_t i; + double d; + } u; + + u.d = d; + + int sign = (u.i >> 63); + int exponent = (u.i >> 52) & 0x7ff; + uint64_t mantissa = u.i & 0x000fffffffffffffull; + + if ((exponent >= 0x3fc) && (exponent <= 0x403) && !(mantissa & 0x0000ffffffffffffull)) + m_value = (sign << 7) | ((exponent & 7) << 4) | (int)(mantissa >> 48); + } + + bool isValid() + { + return m_value != -1; + } + + uint8_t value() + { + return (uint8_t)m_value; + } + +private: + int m_value; +}; typedef enum { SRType_LSL, @@ -398,17 +446,6 @@ private: }; -/* -Some features of the Thumb instruction set are deprecated in ARMv7. Deprecated features affecting -instructions supported by ARMv7-M are as follows: -• use of the PC as <Rd> or <Rm> in a 16-bit ADD (SP plus register) instruction -• use of the SP as <Rm> in a 16-bit ADD (SP plus register) instruction -• use of the SP as <Rm> in a 16-bit CMP (register) instruction -• use of MOV (register) instructions in which <Rd> is the SP or PC and <Rm> is also the SP or PC. -• use of <Rn> as the lowest-numbered register in the register list of a 16-bit STM instruction with base -register writeback -*/ - class ARMv7Assembler { public: ~ARMv7Assembler() @@ -417,7 +454,9 @@ public: } typedef ARMRegisters::RegisterID RegisterID; - typedef ARMRegisters::FPRegisterID FPRegisterID; + typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID; + typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID; + typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID; // (HS, LO, HI, LS) -> (AE, B, A, BE) // (VS, VC) -> (O, NO) @@ -503,53 +542,16 @@ private: return (reg == ARMRegisters::sp) || (reg == ARMRegisters::pc); } - bool isSingleRegister(FPRegisterID reg) - { - // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc). - return !(reg & ~31); - } - - bool isDoubleRegister(FPRegisterID reg) - { - // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc). - return !(reg & ~(31 << 1)); - } - - bool isQuadRegister(FPRegisterID reg) - { - return !(reg & ~(31 << 2)); - } - - uint32_t singleRegisterNum(FPRegisterID reg) - { - ASSERT(isSingleRegister(reg)); - return reg; - } - - uint32_t doubleRegisterNum(FPRegisterID reg) - { - ASSERT(isDoubleRegister(reg)); - return reg >> 1; - } - - uint32_t quadRegisterNum(FPRegisterID reg) - { - ASSERT(isQuadRegister(reg)); - return reg >> 2; - } - - uint32_t singleRegisterMask(FPRegisterID rd, int highBitsShift, int lowBitShift) + uint32_t singleRegisterMask(FPSingleRegisterID rdNum, int highBitsShift, int lowBitShift) { - uint32_t rdNum = singleRegisterNum(rd); uint32_t rdMask = (rdNum >> 1) << highBitsShift; if (rdNum & 1) rdMask |= 1 << lowBitShift; return rdMask; } - uint32_t doubleRegisterMask(FPRegisterID rd, int highBitShift, int lowBitsShift) + uint32_t doubleRegisterMask(FPDoubleRegisterID rdNum, int highBitShift, int lowBitsShift) { - uint32_t rdNum = doubleRegisterNum(rd); uint32_t rdMask = (rdNum & 0xf) << lowBitsShift; if (rdNum & 16) rdMask |= 1 << highBitShift; @@ -558,22 +560,17 @@ private: typedef enum { OP_ADD_reg_T1 = 0x1800, - OP_ADD_S_reg_T1 = 0x1800, OP_SUB_reg_T1 = 0x1A00, - OP_SUB_S_reg_T1 = 0x1A00, OP_ADD_imm_T1 = 0x1C00, - OP_ADD_S_imm_T1 = 0x1C00, OP_SUB_imm_T1 = 0x1E00, - OP_SUB_S_imm_T1 = 0x1E00, OP_MOV_imm_T1 = 0x2000, OP_CMP_imm_T1 = 0x2800, OP_ADD_imm_T2 = 0x3000, - OP_ADD_S_imm_T2 = 0x3000, OP_SUB_imm_T2 = 0x3800, - OP_SUB_S_imm_T2 = 0x3800, OP_AND_reg_T1 = 0x4000, OP_EOR_reg_T1 = 0x4040, OP_TST_reg_T1 = 0x4200, + OP_RSB_imm_T1 = 0x4240, OP_CMP_reg_T1 = 0x4280, OP_ORR_reg_T1 = 0x4300, OP_MVN_reg_T1 = 0x43C0, @@ -603,6 +600,7 @@ private: OP_AND_reg_T2 = 0xEA00, OP_TST_reg_T2 = 0xEA10, OP_ORR_reg_T2 = 0xEA40, + OP_ORR_S_reg_T2 = 0xEA50, OP_ASR_imm_T1 = 0xEA4F, OP_LSL_imm_T1 = 0xEA4F, OP_LSR_imm_T1 = 0xEA4F, @@ -614,6 +612,18 @@ private: OP_SUB_reg_T2 = 0xEBA0, OP_SUB_S_reg_T2 = 0xEBB0, OP_CMP_reg_T2 = 0xEBB0, + OP_VSTR = 0xED00, + OP_VLDR = 0xED10, + OP_VMOV_StoC = 0xEE00, + OP_VMOV_CtoS = 0xEE10, + OP_VMUL_T2 = 0xEE20, + OP_VADD_T2 = 0xEE30, + OP_VSUB_T2 = 0xEE30, + OP_VDIV = 0xEE80, + OP_VCMP_T1 = 0xEEB0, + OP_VCVT_FPIVFP = 0xEEB0, + OP_VMOV_IMM_T2 = 0xEEB0, + OP_VMRS = 0xEEB0, OP_B_T4a = 0xF000, OP_AND_imm_T1 = 0xF000, OP_TST_imm = 0xF010, @@ -627,6 +637,7 @@ private: OP_SUB_imm_T3 = 0xF1A0, OP_SUB_S_imm_T3 = 0xF1B0, OP_CMP_imm_T2 = 0xF1B0, + OP_RSB_imm_T2 = 0xF1C0, OP_ADD_imm_T4 = 0xF200, OP_MOV_imm_T3 = 0xF240, OP_SUB_imm_T4 = 0xF2A0, @@ -652,8 +663,20 @@ private: } OpcodeID1; typedef enum { - OP_B_T4b = 0x9000, + OP_VADD_T2b = 0x0A00, + OP_VDIVb = 0x0A00, + OP_VLDRb = 0x0A00, + OP_VMOV_IMM_T2b = 0x0A00, + OP_VMUL_T2b = 0x0A00, + OP_VSTRb = 0x0A00, + OP_VMOV_CtoSb = 0x0A10, + OP_VMOV_StoCb = 0x0A10, + OP_VMRSb = 0x0A10, + OP_VCMP_T1b = 0x0A40, + OP_VCVT_FPIVFPb = 0x0A40, + OP_VSUB_T2b = 0x0A40, OP_NOP_T2b = 0x8000, + OP_B_T4b = 0x9000, } OpcodeID2; struct FourFours { @@ -784,10 +807,10 @@ public: if (!((rd | rn) & 8)) { if (imm.isUInt3()) { - m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); return; } else if ((rd == rn) && imm.isUInt8()) { - m_formatter.oneWordOp5Reg3Imm8(OP_ADD_S_imm_T2, rd, imm.getUInt8()); + m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8()); return; } } @@ -809,7 +832,7 @@ public: void add_S(RegisterID rd, RegisterID rn, RegisterID rm) { if (!((rd | rn | rm) & 8)) - m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_S_reg_T1, rm, rn, rd); + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd); else add_S(rd, rn, rm, ShiftTypeAndAmount()); } @@ -1219,6 +1242,12 @@ public: mvn(rd, rm, ShiftTypeAndAmount()); } + void neg(RegisterID rd, RegisterID rm) + { + ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0); + sub(rd, zero, rm); + } + void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { ASSERT(!BadReg(rd)); @@ -1245,6 +1274,24 @@ public: orr(rd, rn, rm, ShiftTypeAndAmount()); } + void orr_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) + { + ASSERT(!BadReg(rd)); + ASSERT(!BadReg(rn)); + ASSERT(!BadReg(rm)); + m_formatter.twoWordOp12Reg4FourFours(OP_ORR_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); + } + + void orr_S(RegisterID rd, RegisterID rn, RegisterID rm) + { + if ((rd == rn) && !((rd | rm) & 8)) + m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd); + else if ((rd == rm) && !((rd | rn) & 8)) + m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd); + else + orr_S(rd, rn, rm, ShiftTypeAndAmount()); + } + void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount) { ASSERT(!BadReg(rd)); @@ -1361,6 +1408,19 @@ public: } } + void sub(RegisterID rd, ARMThumbImmediate imm, RegisterID rn) + { + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(imm.isValid()); + ASSERT(imm.isUInt12()); + + if (!((rd | rn) & 8) && !imm.getUInt12()) + m_formatter.oneWordOp10Reg3Reg3(OP_RSB_imm_T1, rn, rd); + else + m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_imm_T2, rn, rd, imm); + } + void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); @@ -1393,10 +1453,10 @@ public: return; } else if (!((rd | rn) & 8)) { if (imm.isUInt3()) { - m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); return; } else if ((rd == rn) && imm.isUInt8()) { - m_formatter.oneWordOp5Reg3Imm8(OP_SUB_S_imm_T2, rd, imm.getUInt8()); + m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8()); return; } } @@ -1418,7 +1478,7 @@ public: void sub_S(RegisterID rd, RegisterID rn, RegisterID rm) { if (!((rd | rn | rm) & 8)) - m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_S_reg_T1, rm, rn, rd); + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd); else sub_S(rd, rn, rm, ShiftTypeAndAmount()); } @@ -1446,62 +1506,75 @@ public: m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn); } - void vadd_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm) + void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm); + } + + void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm) { - m_formatter.vfpOp(0x0b00ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); + m_formatter.vfpOp(OP_VCMP_T1, OP_VCMP_T1b, true, VFPOperand(4), rd, rm); } - void vcmp_F64(FPRegisterID rd, FPRegisterID rm) + void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm) { - m_formatter.vfpOp(0x0bc0eeb4 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rm, 21, 16)); + // boolean values are 64bit (toInt, unsigned, roundZero) + m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm); } - void vcvt_F64_S32(FPRegisterID fd, FPRegisterID sm) + void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm) { - m_formatter.vfpOp(0x0bc0eeb8 | doubleRegisterMask(fd, 6, 28) | singleRegisterMask(sm, 16, 21)); + // boolean values are 64bit (toInt, unsigned, roundZero) + m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm); } - void vcvt_S32_F64(FPRegisterID sd, FPRegisterID fm) + void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { - m_formatter.vfpOp(0x0bc0eebd | singleRegisterMask(sd, 28, 6) | doubleRegisterMask(fm, 21, 16)); + m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm); } - void vldr(FPRegisterID rd, RegisterID rn, int32_t imm) + void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) { - vmem(rd, rn, imm, true); + m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm); } - void vmov(RegisterID rd, FPRegisterID sn) + void vmov_F64_0(FPDoubleRegisterID rd) { - m_formatter.vfpOp(0x0a10ee10 | (rd << 28) | singleRegisterMask(sn, 0, 23)); + m_formatter.vfpOp(OP_VMOV_IMM_T2, OP_VMOV_IMM_T2b, true, VFPOperand(0), rd, VFPOperand(0)); } - void vmov(FPRegisterID sn, RegisterID rd) + void vmov(RegisterID rd, FPSingleRegisterID rn) { - m_formatter.vfpOp(0x0a10ee00 | (rd << 28) | singleRegisterMask(sn, 0, 23)); + ASSERT(!BadReg(rd)); + m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rn, rd, VFPOperand(0)); } - // move FPSCR flags to APSR. - void vmrs_APSR_nzcv_FPSCR() + void vmov(FPSingleRegisterID rd, RegisterID rn) { - m_formatter.vfpOp(0xfa10eef1); + ASSERT(!BadReg(rn)); + m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rd, rn, VFPOperand(0)); } - void vmul_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm) + void vmrs(RegisterID reg = ARMRegisters::pc) { - m_formatter.vfpOp(0x0b00ee20 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); + ASSERT(reg != ARMRegisters::sp); + m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0)); } - void vstr(FPRegisterID rd, RegisterID rn, int32_t imm) + void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { - vmem(rd, rn, imm, false); + m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm); } - void vsub_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm) + void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) { - m_formatter.vfpOp(0x0b40ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); + m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm); } + void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm); + } JmpDst label() { @@ -1654,36 +1727,83 @@ public: static void repatchLoadPtrToLEA(void* where) { ASSERT(!(reinterpret_cast<intptr_t>(where) & 1)); - uint16_t* loadOp = reinterpret_cast<uint16_t*>(where) + 4; - ASSERT((*loadOp & 0xfff0) == OP_LDR_reg_T2); - *loadOp = OP_ADD_reg_T3 | (*loadOp & 0xf); - ExecutableAllocator::cacheFlush(loadOp, sizeof(uint16_t)); + ASSERT((loadOp[0] & 0xfff0) == OP_LDR_reg_T2); + ASSERT((loadOp[1] & 0x0ff0) == 0); + int rn = loadOp[0] & 0xf; + int rt = loadOp[1] >> 12; + int rm = loadOp[1] & 0xf; + + loadOp[0] = OP_ADD_reg_T3 | rn; + loadOp[1] = rt << 8 | rm; + ExecutableAllocator::cacheFlush(loadOp, sizeof(uint32_t)); } private: + // VFP operations commonly take one or more 5-bit operands, typically representing a + // floating point register number. This will commonly be encoded in the instruction + // in two parts, with one single bit field, and one 4-bit field. In the case of + // double precision operands the high bit of the register number will be encoded + // separately, and for single precision operands the high bit of the register number + // will be encoded individually. + // VFPOperand encapsulates a 5-bit VFP operand, with bits 0..3 containing the 4-bit + // field to be encoded together in the instruction (the low 4-bits of a double + // register number, or the high 4-bits of a single register number), and bit 4 + // contains the bit value to be encoded individually. + struct VFPOperand { + explicit VFPOperand(uint32_t value) + : m_value(value) + { + ASSERT(!(m_value & ~0x1f)); + } - // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. - // (i.e. +/-(0..255) 32-bit words) - void vmem(FPRegisterID rd, RegisterID rn, int32_t imm, bool isLoad) - { - bool up; - uint32_t offset; - if (imm < 0) { - offset = -imm; - up = false; - } else { - offset = imm; - up = true; + VFPOperand(FPDoubleRegisterID reg) + : m_value(reg) + { + } + + VFPOperand(RegisterID reg) + : m_value(reg) + { } - // offset is effectively leftshifted by 2 already (the bottom two bits are zero, and not - // reperesented in the instruction. Left shift by 14, to mov it into position 0x00AA0000. - ASSERT((offset & ~(0xff << 2)) == 0); - offset <<= 14; + VFPOperand(FPSingleRegisterID reg) + : m_value(((reg & 1) << 4) | (reg >> 1)) // rotate the lowest bit of 'reg' to the top. + { + } + + uint32_t bits1() + { + return m_value >> 4; + } - m_formatter.vfpOp(0x0b00ed00 | offset | (up << 7) | (isLoad << 4) | doubleRegisterMask(rd, 6, 28) | rn); + uint32_t bits4() + { + return m_value & 0xf; + } + + uint32_t m_value; + }; + + VFPOperand vcvtOp(bool toInteger, bool isUnsigned, bool isRoundZero) + { + // Cannot specify rounding when converting to float. + ASSERT(toInteger || !isRoundZero); + + uint32_t op = 0x8; + if (toInteger) { + // opc2 indicates both toInteger & isUnsigned. + op |= isUnsigned ? 0x4 : 0x5; + // 'op' field in instruction is isRoundZero + if (isRoundZero) + op |= 0x10; + } else { + // 'op' field in instruction is isUnsigned + if (!isUnsigned) + op |= 0x10; + } + return VFPOperand(op); } static void setInt32(void* code, uint32_t value) @@ -1873,11 +1993,35 @@ private: m_buffer.putShort((reg2 << 12) | imm); } - void vfpOp(int32_t op) + // Formats up instructions of the pattern: + // 111111111B11aaaa:bbbb222SA2C2cccc + // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit. + // Operands provide 5 bit values of the form Aaaaa, Bbbbb, Ccccc. + void vfpOp(OpcodeID1 op1, OpcodeID2 op2, bool size, VFPOperand a, VFPOperand b, VFPOperand c) { - m_buffer.putInt(op); + ASSERT(!(op1 & 0x004f)); + ASSERT(!(op2 & 0xf1af)); + m_buffer.putShort(op1 | b.bits1() << 6 | a.bits4()); + m_buffer.putShort(op2 | b.bits4() << 12 | size << 8 | a.bits1() << 7 | c.bits1() << 5 | c.bits4()); } + // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. + // (i.e. +/-(0..255) 32-bit words) + void vfpMemOp(OpcodeID1 op1, OpcodeID2 op2, bool size, RegisterID rn, VFPOperand rd, int32_t imm) + { + bool up = true; + if (imm < 0) { + imm = -imm; + up = false; + } + + uint32_t offset = imm; + ASSERT(!(offset & ~0x3fc)); + offset >>= 2; + + m_buffer.putShort(op1 | (up << 7) | rd.bits1() << 6 | rn); + m_buffer.putShort(op2 | rd.bits4() << 12 | size << 8 | offset); + } // Administrative methods: diff --git a/JavaScriptCore/assembler/AbstractMacroAssembler.h b/JavaScriptCore/assembler/AbstractMacroAssembler.h index 1c7f269..aab9089 100644 --- a/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -49,7 +49,6 @@ public: class Jump; typedef typename AssemblerType::RegisterID RegisterID; - typedef typename AssemblerType::FPRegisterID FPRegisterID; typedef typename AssemblerType::JmpSrc JmpSrc; typedef typename AssemblerType::JmpDst JmpDst; diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h index 7f11ca9..1c64071 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -40,6 +40,8 @@ class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> { static const int DoubleConditionBitSpecial = 0x10; COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes); public: + typedef ARMRegisters::FPRegisterID FPRegisterID; + enum Condition { Equal = ARMAssembler::EQ, NotEqual = ARMAssembler::NE, diff --git a/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 380d5f8..64513fd 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -38,10 +38,13 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7? // - dTR is likely used more than aTR, and we'll get better instruction // encoding if it's in the low 8 registers. - static const ARMRegisters::RegisterID dataTempRegister = ARMRegisters::ip; + static const RegisterID dataTempRegister = ARMRegisters::ip; static const RegisterID addressTempRegister = ARMRegisters::r3; - static const FPRegisterID fpTempRegister = ARMRegisters::d7; + static const ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7; + inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); } + +public: struct ArmAddress { enum AddressType { HasOffset, @@ -73,6 +76,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { }; public: + typedef ARMRegisters::FPDoubleRegisterID FPRegisterID; static const Scale ScalePtr = TimesFour; @@ -222,6 +226,11 @@ public: m_assembler.smull(dest, dataTempRegister, src, dataTempRegister); } + void neg32(RegisterID srcDest) + { + m_assembler.neg(srcDest, srcDest); + } + void not32(RegisterID srcDest) { m_assembler.mvn(srcDest, srcDest); @@ -540,6 +549,12 @@ public: m_assembler.vldr(dest, base, offset); } + void loadDouble(const void* address, FPRegisterID dest) + { + move(ImmPtr(address), addressTempRegister); + m_assembler.vldr(dest, addressTempRegister, 0); + } + void storeDouble(FPRegisterID src, ImplicitAddress address) { RegisterID base = address.base; @@ -566,6 +581,11 @@ public: addDouble(fpTempRegister, dest); } + void divDouble(FPRegisterID src, FPRegisterID dest) + { + m_assembler.vdiv_F64(dest, dest, src); + } + void subDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.vsub_F64(dest, dest, src); @@ -595,14 +615,30 @@ public: void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { - m_assembler.vmov(fpTempRegister, src); - m_assembler.vcvt_F64_S32(dest, fpTempRegister); + m_assembler.vmov(fpTempRegisterAsSingle(), src); + m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); + } + + void convertInt32ToDouble(Address address, FPRegisterID dest) + { + // Fixme: load directly into the fpr! + load32(address, dataTempRegister); + m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister); + m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); + } + + void convertInt32ToDouble(AbsoluteAddress address, FPRegisterID dest) + { + // Fixme: load directly into the fpr! + load32(address.m_ptr, dataTempRegister); + m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister); + m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); } Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) { m_assembler.vcmp_F64(left, right); - m_assembler.vmrs_APSR_nzcv_FPSCR(); + m_assembler.vmrs(); if (cond == DoubleNotEqual) { // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump. @@ -629,6 +665,27 @@ public: return jump(); } + // Convert 'src' to an integer, and places the resulting 'dest'. + // If the result is not representable as a 32 bit value, branch. + // May also branch for some values that are representable in 32 bits + // (specifically, in this case, 0). + void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID) + { + m_assembler.vcvtr_S32_F64(fpTempRegisterAsSingle(), src); + m_assembler.vmov(dest, fpTempRegisterAsSingle()); + + // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. + m_assembler.vcvt_F64_S32(fpTempRegister, fpTempRegisterAsSingle()); + failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister)); + + // If the result is zero, it might have been -0.0, and the double comparison won't catch this! + failureCases.append(branchTest32(Zero, dest)); + } + + void zeroDouble(FPRegisterID dest) + { + m_assembler.vmov_F64_0(dest); + } // Stack manipulation operations: // @@ -970,6 +1027,13 @@ public: return branch32(NotEqual, addressTempRegister, dataTempRegister); } + Jump branchOr32(Condition cond, RegisterID src, RegisterID dest) + { + ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); + m_assembler.orr_S(dest, dest, src); + return Jump(makeBranch(cond)); + } + Jump branchSub32(Condition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1034,6 +1098,12 @@ public: m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); } + void set32(Condition cond, Address left, RegisterID right, RegisterID dest) + { + load32(left, dataTempRegister); + set32(cond, dataTempRegister, right, dest); + } + void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest) { compare32(left, right); @@ -1042,6 +1112,21 @@ public: m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); } + void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest) + { + set32(cond, left, right, dest); + } + + void set8(Condition cond, Address left, RegisterID right, RegisterID dest) + { + set32(cond, left, right, dest); + } + + void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest) + { + set32(cond, left, right, dest); + } + // FIXME: // The mask should be optional... paerhaps the argument order should be // dest-src, operations always have a dest? ... possibly not true, considering diff --git a/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/JavaScriptCore/assembler/MacroAssemblerMIPS.h index 88132f7..3bb9e75 100644 --- a/JavaScriptCore/assembler/MacroAssemblerMIPS.h +++ b/JavaScriptCore/assembler/MacroAssemblerMIPS.h @@ -36,6 +36,7 @@ namespace JSC { class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> { public: + typedef MIPSRegisters::FPRegisterID FPRegisterID; MacroAssemblerMIPS() : m_fixedWidth(false) diff --git a/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/JavaScriptCore/assembler/MacroAssemblerX86Common.h index 7296193..cb86da7 100644 --- a/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -39,6 +39,7 @@ class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> { static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial; public: + typedef X86Assembler::FPRegisterID FPRegisterID; enum Condition { Equal = X86Assembler::ConditionE, diff --git a/JavaScriptCore/bytecode/Opcode.cpp b/JavaScriptCore/bytecode/Opcode.cpp index bb7696d..8f7f01f 100644 --- a/JavaScriptCore/bytecode/Opcode.cpp +++ b/JavaScriptCore/bytecode/Opcode.cpp @@ -101,7 +101,7 @@ OpcodeStats::~OpcodeStats() for (int j = 0; j < numOpcodeIDs; ++j) totalInstructionPairs += opcodePairCounts[i][j]; - int sortedIndices[numOpcodeIDs]; + FixedArray<int, numOpcodeIDs> sortedIndices; for (int i = 0; i < numOpcodeIDs; ++i) sortedIndices[i] = i; qsort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices); diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index 7c5bc6f..8160249 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/JavaScriptCore/interpreter/Interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> * * Redistribution and use in source and binary forms, with or without @@ -3693,9 +3693,10 @@ skip_id_custom_self: int argsOffset = vPC[2].u.operand; JSValue arguments = callFrame->r(argsOffset).jsValue(); - int32_t argCount = 0; + uint32_t argCount = 0; if (!arguments) { argCount = (uint32_t)(callFrame->argumentCount()); + argCount = min<uint32_t>(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3703,9 +3704,9 @@ skip_id_custom_self: goto vm_throw; } ASSERT(!asFunction(callFrame->callee())->isHostFunction()); - int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); - int32_t inplaceArgs = min(argCount, expectedParams); - int32_t i = 0; + uint32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); + uint32_t inplaceArgs = min(argCount, expectedParams); + uint32_t i = 0; Register* argStore = callFrame->registers() + argsOffset; // First step is to copy the "expected" parameters from their normal location relative to the callframe @@ -3722,6 +3723,7 @@ skip_id_custom_self: if (asObject(arguments)->classInfo() == &Arguments::info) { Arguments* args = asArguments(arguments); argCount = args->numProvidedArguments(callFrame); + argCount = min<uint32_t>(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3732,6 +3734,7 @@ skip_id_custom_self: } else if (isJSArray(&callFrame->globalData(), arguments)) { JSArray* array = asArray(arguments); argCount = array->length(); + argCount = min<uint32_t>(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3742,6 +3745,7 @@ skip_id_custom_self: } else if (asObject(arguments)->inherits(&JSArray::info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); + argCount = min<uint32_t>(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3749,7 +3753,7 @@ skip_id_custom_self: goto vm_throw; } Register* argsBuffer = callFrame->registers() + argsOffset; - for (int32_t i = 0; i < argCount; ++i) { + for (uint32_t i = 0; i < argCount; ++i) { argsBuffer[i] = asObject(arguments)->get(callFrame, i); CHECK_FOR_EXCEPTION(); } diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index 9a34931..8e86d40 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -241,6 +241,37 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon restoreReturnAddressBeforeReturn(regT3); +#elif CPU(MIPS) + // Load caller frame's scope chain into this callframe so that whatever we call can + // get to its global data. + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); + emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + + preserveReturnAddressAfterCall(regT3); // Callee preserved + emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + + // Calling convention: f(a0, a1, a2, a3); + // Host function signature: f(ExecState*); + + // Allocate stack space for 16 bytes (8-byte aligned) + // 16 bytes (unused) for 4 arguments + subPtr(Imm32(16), stackPointerRegister); + + // Setup arg0 + move(callFrameRegister, MIPSRegisters::a0); + + // Call + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2); + loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. + call(Address(regT2, executableOffsetToFunction)); + + // Restore stack space + addPtr(Imm32(16), stackPointerRegister); + + restoreReturnAddressBeforeReturn(regT3); + #elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) #error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." #else diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index c4a6507..30a9898 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -1531,17 +1531,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (stubInfo->accessType == access_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); - stubInfo->initGetByIdSelfList(polymorphicStructureList, 2); + stubInfo->initGetByIdSelfList(polymorphicStructureList, 1); } else { polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList; listIndex = stubInfo->u.getByIdSelfList.listSize; - stubInfo->u.getByIdSelfList.listSize++; } + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + stubInfo->u.getByIdSelfList.listSize++; + JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset()); - JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset()); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); + } } else ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); return JSValue::encode(result); @@ -1566,13 +1567,14 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str case access_get_by_id_proto_list: prototypeStructureList = stubInfo->u.getByIdProtoList.structureList; listIndex = stubInfo->u.getByIdProtoList.listSize; - stubInfo->u.getByIdProtoList.listSize++; + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) + stubInfo->u.getByIdProtoList.listSize++; break; default: ASSERT_NOT_REACHED(); } - ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE); + ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE); return prototypeStructureList; } @@ -1647,21 +1649,24 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset); - JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + } } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) { ASSERT(!asCell(baseValue)->structure()->isDictionary()); int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + StructureChain* protoChain = structure->prototypeChain(callFrame); + JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset); - StructureChain* protoChain = structure->prototypeChain(callFrame); - JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + } } else ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); @@ -2452,6 +2457,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) if (!arguments) { int providedParams = callFrame->registers()[RegisterFile::ArgumentCount].i() - 1; argCount = providedParams; + argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2487,6 +2493,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) if (asObject(arguments)->classInfo() == &Arguments::info) { Arguments* argsObject = asArguments(arguments); argCount = argsObject->numProvidedArguments(callFrame); + argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2497,6 +2504,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) } else if (isJSArray(&callFrame->globalData(), arguments)) { JSArray* array = asArray(arguments); argCount = array->length(); + argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2507,6 +2515,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) } else if (asObject(arguments)->inherits(&JSArray::info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); + argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y deleted file mode 100644 index 4d6e7d1..0000000 --- a/JavaScriptCore/parser/Grammar.y +++ /dev/null @@ -1,2099 +0,0 @@ -%pure_parser - -%{ - -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" - -#include "JSObject.h" -#include "JSString.h" -#include "Lexer.h" -#include "NodeConstructors.h" -#include "NodeInfo.h" -#include <stdlib.h> -#include <string.h> -#include <wtf/MathExtras.h> - -#define YYMALLOC fastMalloc -#define YYFREE fastFree - -#define YYMAXDEPTH 10000 -#define YYENABLE_NLS 0 - -// Default values for bison. -#define YYDEBUG 0 // Set to 1 to debug a parse error. -#define jscyydebug 0 // Set to 1 to debug a parse error. -#if !OS(DARWIN) -// Avoid triggering warnings in older bison by not setting this on the Darwin platform. -// FIXME: Is this still needed? -#define YYERROR_VERBOSE -#endif - -int jscyyerror(const char*); - -static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); - -#define GLOBAL_DATA static_cast<JSGlobalData*>(globalPtr) -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*GLOBAL_DATA->lexer, yychar)) YYABORT; } while (0) - -using namespace JSC; -using namespace std; - -static ExpressionNode* makeAssignNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end); -static ExpressionNode* makePrefixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); -static ExpressionNode* makePostfixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); -static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData*, const Identifier& getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); -static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData*, ExpressionNodeInfo function, ArgumentsNodeInfo, int start, int divot, int end); -static ExpressionNode* makeTypeOfNode(JSGlobalData*, ExpressionNode*); -static ExpressionNode* makeDeleteNode(JSGlobalData*, ExpressionNode*, int start, int divot, int end); -static ExpressionNode* makeNegateNode(JSGlobalData*, ExpressionNode*); -static NumberNode* makeNumberNode(JSGlobalData*, double); -static ExpressionNode* makeBitwiseNotNode(JSGlobalData*, ExpressionNode*); -static ExpressionNode* makeMultNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static ExpressionNode* makeDivNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static ExpressionNode* makeAddNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static ExpressionNode* makeSubNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static ExpressionNode* makeLeftShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static ExpressionNode* makeRightShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); -static StatementNode* makeVarStatementNode(JSGlobalData*, ExpressionNode*); -static ExpressionNode* combineCommaNodes(JSGlobalData*, ExpressionNode* list, ExpressionNode* init); - -#if COMPILER(MSVC) - -#pragma warning(disable: 4065) -#pragma warning(disable: 4244) -#pragma warning(disable: 4702) - -#endif - -#define YYPARSE_PARAM globalPtr -#define YYLEX_PARAM globalPtr - -template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, - ParserArenaData<DeclarationStacks::VarStack>* varDecls, - ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, - CodeFeatures info, int numConstants) -{ - ASSERT((info & ~AllFeatures) == 0); - NodeDeclarationInfo<T> result = { node, varDecls, funcDecls, info, numConstants }; - return result; -} - -template <typename T> inline NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) -{ - ASSERT((info & ~AllFeatures) == 0); - NodeInfo<T> result = { node, info, numConstants }; - return result; -} - -template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) -{ - // decls1 or both are null - if (!decls1) - return decls2; - // only decls1 is non-null - if (!decls2) - return decls1; - - // Both are non-null - decls1->data.append(decls2->data); - - // Manually release as much as possible from the now-defunct declaration lists - // to avoid accumulating so many unused heap allocated vectors. - decls2->data.clear(); - - return decls1; -} - -static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) -{ - if (!varDecls) - varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>; - - varDecls->data.append(make_pair(&ident, attrs)); -} - -static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) -{ - unsigned attrs = DeclarationStacks::IsConstant; - if (decl->hasInitializer()) - attrs |= DeclarationStacks::HasInitializer; - appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs); -} - -%} - -%union { - int intValue; - double doubleValue; - const Identifier* ident; - - // expression subtrees - ExpressionNodeInfo expressionNode; - FuncDeclNodeInfo funcDeclNode; - PropertyNodeInfo propertyNode; - ArgumentsNodeInfo argumentsNode; - ConstDeclNodeInfo constDeclNode; - CaseBlockNodeInfo caseBlockNode; - CaseClauseNodeInfo caseClauseNode; - FuncExprNodeInfo funcExprNode; - - // statement nodes - StatementNodeInfo statementNode; - FunctionBodyNode* functionBodyNode; - ProgramNode* programNode; - - SourceElementsInfo sourceElements; - PropertyListInfo propertyList; - ArgumentListInfo argumentList; - VarDeclListInfo varDeclList; - ConstDeclListInfo constDeclList; - ClauseListInfo clauseList; - ElementListInfo elementList; - ParameterListInfo parameterList; - - Operator op; -} - -%{ - -template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end) -{ - statement->setLoc(start.first_line, end.last_line); -} - -static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end) -{ - node->setExceptionSourceCode(divot, divot - start, end - divot); -} - -%} - -%start Program - -/* literals */ -%token NULLTOKEN TRUETOKEN FALSETOKEN - -/* keywords */ -%token BREAK CASE DEFAULT FOR NEW VAR CONSTTOKEN CONTINUE -%token FUNCTION RETURN VOIDTOKEN DELETETOKEN -%token IF THISTOKEN DO WHILE INTOKEN INSTANCEOF TYPEOF -%token SWITCH WITH RESERVED -%token THROW TRY CATCH FINALLY -%token DEBUGGER - -/* give an if without an else higher precedence than an else to resolve the ambiguity */ -%nonassoc IF_WITHOUT_ELSE -%nonassoc ELSE - -/* punctuators */ -%token EQEQ NE /* == and != */ -%token STREQ STRNEQ /* === and !== */ -%token LE GE /* < and > */ -%token OR AND /* || and && */ -%token PLUSPLUS MINUSMINUS /* ++ and -- */ -%token LSHIFT /* << */ -%token RSHIFT URSHIFT /* >> and >>> */ -%token PLUSEQUAL MINUSEQUAL /* += and -= */ -%token MULTEQUAL DIVEQUAL /* *= and /= */ -%token LSHIFTEQUAL /* <<= */ -%token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */ -%token ANDEQUAL MODEQUAL /* &= and %= */ -%token XOREQUAL OREQUAL /* ^= and |= */ -%token <intValue> OPENBRACE /* { (with char offset) */ -%token <intValue> CLOSEBRACE /* } (with char offset) */ - -/* terminal types */ -%token <doubleValue> NUMBER -%token <ident> IDENT STRING - -/* automatically inserted semicolon */ -%token AUTOPLUSPLUS AUTOMINUSMINUS - -/* non-terminal types */ -%type <expressionNode> Literal ArrayLiteral - -%type <expressionNode> PrimaryExpr PrimaryExprNoBrace -%type <expressionNode> MemberExpr MemberExprNoBF /* BF => brace or function */ -%type <expressionNode> NewExpr NewExprNoBF -%type <expressionNode> CallExpr CallExprNoBF -%type <expressionNode> LeftHandSideExpr LeftHandSideExprNoBF -%type <expressionNode> PostfixExpr PostfixExprNoBF -%type <expressionNode> UnaryExpr UnaryExprNoBF UnaryExprCommon -%type <expressionNode> MultiplicativeExpr MultiplicativeExprNoBF -%type <expressionNode> AdditiveExpr AdditiveExprNoBF -%type <expressionNode> ShiftExpr ShiftExprNoBF -%type <expressionNode> RelationalExpr RelationalExprNoIn RelationalExprNoBF -%type <expressionNode> EqualityExpr EqualityExprNoIn EqualityExprNoBF -%type <expressionNode> BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF -%type <expressionNode> BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF -%type <expressionNode> BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF -%type <expressionNode> LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF -%type <expressionNode> LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF -%type <expressionNode> ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF -%type <expressionNode> AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF -%type <expressionNode> Expr ExprNoIn ExprNoBF - -%type <expressionNode> ExprOpt ExprNoInOpt - -%type <statementNode> Statement Block -%type <statementNode> VariableStatement ConstStatement EmptyStatement ExprStatement -%type <statementNode> IfStatement IterationStatement ContinueStatement -%type <statementNode> BreakStatement ReturnStatement WithStatement -%type <statementNode> SwitchStatement LabelledStatement -%type <statementNode> ThrowStatement TryStatement -%type <statementNode> DebuggerStatement - -%type <expressionNode> Initializer InitializerNoIn -%type <statementNode> FunctionDeclaration -%type <funcExprNode> FunctionExpr -%type <functionBodyNode> FunctionBody -%type <sourceElements> SourceElements -%type <parameterList> FormalParameterList -%type <op> AssignmentOperator -%type <argumentsNode> Arguments -%type <argumentList> ArgumentList -%type <varDeclList> VariableDeclarationList VariableDeclarationListNoIn -%type <constDeclList> ConstDeclarationList -%type <constDeclNode> ConstDeclaration -%type <caseBlockNode> CaseBlock -%type <caseClauseNode> CaseClause DefaultClause -%type <clauseList> CaseClauses CaseClausesOpt -%type <intValue> Elision ElisionOpt -%type <elementList> ElementList -%type <propertyNode> Property -%type <propertyList> PropertyList -%% - -// FIXME: There are currently two versions of the grammar in this file, the normal one, and the NoNodes version used for -// lazy recompilation of FunctionBodyNodes. We should move to generating the two versions from a script to avoid bugs. -// In the mean time, make sure to make any changes to the grammar in both versions. - -Literal: - NULLTOKEN { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NullNode(GLOBAL_DATA), 0, 1); } - | TRUETOKEN { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, true), 0, 1); } - | FALSETOKEN { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, false), 0, 1); } - | NUMBER { $$ = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, $1), 0, 1); } - | STRING { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *$1), 0, 1); } - | '/' /* regexp */ { - Lexer& l = *GLOBAL_DATA->lexer; - const Identifier* pattern; - const Identifier* flags; - if (!l.scanRegExp(pattern, flags)) - YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); - int size = pattern->size() + 2; // + 2 for the two /'s - setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); - $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); - } - | DIVEQUAL /* regexp with /= */ { - Lexer& l = *GLOBAL_DATA->lexer; - const Identifier* pattern; - const Identifier* flags; - if (!l.scanRegExp(pattern, flags, '=')) - YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); - int size = pattern->size() + 2; // + 2 for the two /'s - setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); - $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); - } -; - -Property: - IDENT ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | STRING ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | NUMBER ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, $1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, 0, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); if (!$$.m_node) YYABORT; } - | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, $4.m_node.head, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); - if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - setStatementLocation($7, @6, @8); - if (!$$.m_node) - YYABORT; - } -; - -PropertyList: - Property { $$.m_node.head = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, $1.m_node); - $$.m_node.tail = $$.m_node.head; - $$.m_features = $1.m_features; - $$.m_numConstants = $1.m_numConstants; } - | PropertyList ',' Property { $$.m_node.head = $1.m_node.head; - $$.m_node.tail = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, $3.m_node, $1.m_node.tail); - $$.m_features = $1.m_features | $3.m_features; - $$.m_numConstants = $1.m_numConstants + $3.m_numConstants; } -; - -PrimaryExpr: - PrimaryExprNoBrace - | OPENBRACE CLOSEBRACE { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA), 0, 0); } - | OPENBRACE PropertyList CLOSEBRACE { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); } - /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */ - | OPENBRACE PropertyList ',' CLOSEBRACE { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); } -; - -PrimaryExprNoBrace: - THISTOKEN { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ThisNode(GLOBAL_DATA), ThisFeature, 0); } - | Literal - | ArrayLiteral - | IDENT { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ResolveNode(GLOBAL_DATA, *$1, @1.first_column), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); } - | '(' Expr ')' { $$ = $2; } -; - -ArrayLiteral: - '[' ElisionOpt ']' { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $2), 0, $2 ? 1 : 0); } - | '[' ElementList ']' { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); } - | '[' ElementList ',' ElisionOpt ']' { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $4, $2.m_node.head), $2.m_features, $4 ? $2.m_numConstants + 1 : $2.m_numConstants); } -; - -ElementList: - ElisionOpt AssignmentExpr { $$.m_node.head = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, $1, $2.m_node); - $$.m_node.tail = $$.m_node.head; - $$.m_features = $2.m_features; - $$.m_numConstants = $2.m_numConstants; } - | ElementList ',' ElisionOpt AssignmentExpr - { $$.m_node.head = $1.m_node.head; - $$.m_node.tail = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, $1.m_node.tail, $3, $4.m_node); - $$.m_features = $1.m_features | $4.m_features; - $$.m_numConstants = $1.m_numConstants + $4.m_numConstants; } -; - -ElisionOpt: - /* nothing */ { $$ = 0; } - | Elision -; - -Elision: - ',' { $$ = 1; } - | Elision ',' { $$ = $1 + 1; } -; - -MemberExpr: - PrimaryExpr - | FunctionExpr { $$ = createNodeInfo<ExpressionNode*>($1.m_node, $1.m_features, $1.m_numConstants); } - | MemberExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); - } - | MemberExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); - } - | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); - } -; - -MemberExprNoBF: - PrimaryExprNoBrace - | MemberExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); - } - | MemberExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); - } - | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); - } -; - -NewExpr: - MemberExpr - | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); - } -; - -NewExprNoBF: - MemberExprNoBF - | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); - } -; - -CallExpr: - MemberExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); - } - | CallExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } -; - -CallExprNoBF: - MemberExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); - } - | CallExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); - } -; - -Arguments: - '(' ')' { $$ = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA), 0, 0); } - | '(' ArgumentList ')' { $$ = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); } -; - -ArgumentList: - AssignmentExpr { $$.m_node.head = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, $1.m_node); - $$.m_node.tail = $$.m_node.head; - $$.m_features = $1.m_features; - $$.m_numConstants = $1.m_numConstants; } - | ArgumentList ',' AssignmentExpr { $$.m_node.head = $1.m_node.head; - $$.m_node.tail = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, $1.m_node.tail, $3.m_node); - $$.m_features = $1.m_features | $3.m_features; - $$.m_numConstants = $1.m_numConstants + $3.m_numConstants; } -; - -LeftHandSideExpr: - NewExpr - | CallExpr -; - -LeftHandSideExprNoBF: - NewExprNoBF - | CallExprNoBF -; - -PostfixExpr: - LeftHandSideExpr - | LeftHandSideExpr PLUSPLUS { $$ = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus, @1.first_column, @1.last_column, @2.last_column), $1.m_features | AssignFeature, $1.m_numConstants); } - | LeftHandSideExpr MINUSMINUS { $$ = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus, @1.first_column, @1.last_column, @2.last_column), $1.m_features | AssignFeature, $1.m_numConstants); } -; - -PostfixExprNoBF: - LeftHandSideExprNoBF - | LeftHandSideExprNoBF PLUSPLUS { $$ = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus, @1.first_column, @1.last_column, @2.last_column), $1.m_features | AssignFeature, $1.m_numConstants); } - | LeftHandSideExprNoBF MINUSMINUS { $$ = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus, @1.first_column, @1.last_column, @2.last_column), $1.m_features | AssignFeature, $1.m_numConstants); } -; - -UnaryExprCommon: - DELETETOKEN UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeDeleteNode(GLOBAL_DATA, $2.m_node, @1.first_column, @2.last_column, @2.last_column), $2.m_features, $2.m_numConstants); } - | VOIDTOKEN UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) VoidNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants + 1); } - | TYPEOF UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeTypeOfNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); } - | PLUSPLUS UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); } - | AUTOPLUSPLUS UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); } - | MINUSMINUS UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); } - | AUTOMINUSMINUS UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); } - | '+' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); } - | '-' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeNegateNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); } - | '~' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeBitwiseNotNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); } - | '!' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalNotNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); } - -UnaryExpr: - PostfixExpr - | UnaryExprCommon -; - -UnaryExprNoBF: - PostfixExprNoBF - | UnaryExprCommon -; - -MultiplicativeExpr: - UnaryExpr - | MultiplicativeExpr '*' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | MultiplicativeExpr '/' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | MultiplicativeExpr '%' UnaryExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -MultiplicativeExprNoBF: - UnaryExprNoBF - | MultiplicativeExprNoBF '*' UnaryExpr - { $$ = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | MultiplicativeExprNoBF '/' UnaryExpr - { $$ = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | MultiplicativeExprNoBF '%' UnaryExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -AdditiveExpr: - MultiplicativeExpr - | AdditiveExpr '+' MultiplicativeExpr { $$ = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | AdditiveExpr '-' MultiplicativeExpr { $$ = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -AdditiveExprNoBF: - MultiplicativeExprNoBF - | AdditiveExprNoBF '+' MultiplicativeExpr - { $$ = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | AdditiveExprNoBF '-' MultiplicativeExpr - { $$ = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -ShiftExpr: - AdditiveExpr - | ShiftExpr LSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | ShiftExpr RSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | ShiftExpr URSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -ShiftExprNoBF: - AdditiveExprNoBF - | ShiftExprNoBF LSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | ShiftExprNoBF RSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | ShiftExprNoBF URSHIFT AdditiveExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -RelationalExpr: - ShiftExpr - | RelationalExpr '<' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExpr '>' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExpr LE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExpr GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExpr INTOKEN ShiftExpr { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -RelationalExprNoIn: - ShiftExpr - | RelationalExprNoIn '<' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoIn '>' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoIn LE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoIn GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoIn INSTANCEOF ShiftExpr - { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -RelationalExprNoBF: - ShiftExprNoBF - | RelationalExprNoBF '<' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoBF '>' ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoBF LE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoBF GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoBF INSTANCEOF ShiftExpr - { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | RelationalExprNoBF INTOKEN ShiftExpr - { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); - $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -EqualityExpr: - RelationalExpr - | EqualityExpr EQEQ RelationalExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExpr NE RelationalExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExpr STREQ RelationalExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExpr STRNEQ RelationalExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -EqualityExprNoIn: - RelationalExprNoIn - | EqualityExprNoIn EQEQ RelationalExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoIn NE RelationalExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoIn STREQ RelationalExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoIn STRNEQ RelationalExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -EqualityExprNoBF: - RelationalExprNoBF - | EqualityExprNoBF EQEQ RelationalExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoBF NE RelationalExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoBF STREQ RelationalExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } - | EqualityExprNoBF STRNEQ RelationalExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseANDExpr: - EqualityExpr - | BitwiseANDExpr '&' EqualityExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseANDExprNoIn: - EqualityExprNoIn - | BitwiseANDExprNoIn '&' EqualityExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseANDExprNoBF: - EqualityExprNoBF - | BitwiseANDExprNoBF '&' EqualityExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseXORExpr: - BitwiseANDExpr - | BitwiseXORExpr '^' BitwiseANDExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseXORExprNoIn: - BitwiseANDExprNoIn - | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseXORExprNoBF: - BitwiseANDExprNoBF - | BitwiseXORExprNoBF '^' BitwiseANDExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseORExpr: - BitwiseXORExpr - | BitwiseORExpr '|' BitwiseXORExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseORExprNoIn: - BitwiseXORExprNoIn - | BitwiseORExprNoIn '|' BitwiseXORExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -BitwiseORExprNoBF: - BitwiseXORExprNoBF - | BitwiseORExprNoBF '|' BitwiseXORExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalANDExpr: - BitwiseORExpr - | LogicalANDExpr AND BitwiseORExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalANDExprNoIn: - BitwiseORExprNoIn - | LogicalANDExprNoIn AND BitwiseORExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalANDExprNoBF: - BitwiseORExprNoBF - | LogicalANDExprNoBF AND BitwiseORExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalORExpr: - LogicalANDExpr - | LogicalORExpr OR LogicalANDExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalORExprNoIn: - LogicalANDExprNoIn - | LogicalORExprNoIn OR LogicalANDExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -LogicalORExprNoBF: - LogicalANDExprNoBF - | LogicalORExprNoBF OR LogicalANDExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -ConditionalExpr: - LogicalORExpr - | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); } -; - -ConditionalExprNoIn: - LogicalORExprNoIn - | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); } -; - -ConditionalExprNoBF: - LogicalORExprNoBF - | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr - { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); } -; - -AssignmentExpr: - ConditionalExpr - | LeftHandSideExpr AssignmentOperator AssignmentExpr - { $$ = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_features & AssignFeature, $3.m_features & AssignFeature, - @1.first_column, @2.first_column + 1, @3.last_column), $1.m_features | $3.m_features | AssignFeature, $1.m_numConstants + $3.m_numConstants); - } -; - -AssignmentExprNoIn: - ConditionalExprNoIn - | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn - { $$ = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_features & AssignFeature, $3.m_features & AssignFeature, - @1.first_column, @2.first_column + 1, @3.last_column), $1.m_features | $3.m_features | AssignFeature, $1.m_numConstants + $3.m_numConstants); - } -; - -AssignmentExprNoBF: - ConditionalExprNoBF - | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr - { $$ = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_features & AssignFeature, $3.m_features & AssignFeature, - @1.first_column, @2.first_column + 1, @3.last_column), $1.m_features | $3.m_features | AssignFeature, $1.m_numConstants + $3.m_numConstants); - } -; - -AssignmentOperator: - '=' { $$ = OpEqual; } - | PLUSEQUAL { $$ = OpPlusEq; } - | MINUSEQUAL { $$ = OpMinusEq; } - | MULTEQUAL { $$ = OpMultEq; } - | DIVEQUAL { $$ = OpDivEq; } - | LSHIFTEQUAL { $$ = OpLShift; } - | RSHIFTEQUAL { $$ = OpRShift; } - | URSHIFTEQUAL { $$ = OpURShift; } - | ANDEQUAL { $$ = OpAndEq; } - | XOREQUAL { $$ = OpXOrEq; } - | OREQUAL { $$ = OpOrEq; } - | MODEQUAL { $$ = OpModEq; } -; - -Expr: - AssignmentExpr - | Expr ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -ExprNoIn: - AssignmentExprNoIn - | ExprNoIn ',' AssignmentExprNoIn { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -ExprNoBF: - AssignmentExprNoBF - | ExprNoBF ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } -; - -Statement: - Block - | VariableStatement - | ConstStatement - | FunctionDeclaration - | EmptyStatement - | ExprStatement - | IfStatement - | IterationStatement - | ContinueStatement - | BreakStatement - | ReturnStatement - | WithStatement - | SwitchStatement - | LabelledStatement - | ThrowStatement - | TryStatement - | DebuggerStatement -; - -Block: - OPENBRACE CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); } - | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } -; - -VariableStatement: - VAR VariableDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } - | VAR VariableDeclarationList error { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @2); - AUTO_SEMICOLON; } -; - -VariableDeclarationList: - IDENT { $$.m_node = 0; - $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, 0); - $$.m_funcDeclarations = 0; - $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; - $$.m_numConstants = 0; - } - | IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); - $$.m_node = node; - $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); - $$.m_funcDeclarations = 0; - $$.m_features = ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features; - $$.m_numConstants = $2.m_numConstants; - } - | VariableDeclarationList ',' IDENT - { $$.m_node = $1.m_node; - $$.m_varDeclarations = $1.m_varDeclarations; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, 0); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); - $$.m_numConstants = $1.m_numConstants; - } - | VariableDeclarationList ',' IDENT Initializer - { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); - $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); - $$.m_varDeclarations = $1.m_varDeclarations; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features; - $$.m_numConstants = $1.m_numConstants + $4.m_numConstants; - } -; - -VariableDeclarationListNoIn: - IDENT { $$.m_node = 0; - $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, 0); - $$.m_funcDeclarations = 0; - $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; - $$.m_numConstants = 0; - } - | IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); - $$.m_node = node; - $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); - $$.m_funcDeclarations = 0; - $$.m_features = ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features; - $$.m_numConstants = $2.m_numConstants; - } - | VariableDeclarationListNoIn ',' IDENT - { $$.m_node = $1.m_node; - $$.m_varDeclarations = $1.m_varDeclarations; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, 0); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); - $$.m_numConstants = $1.m_numConstants; - } - | VariableDeclarationListNoIn ',' IDENT InitializerNoIn - { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); - $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); - $$.m_varDeclarations = $1.m_varDeclarations; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features; - $$.m_numConstants = $1.m_numConstants + $4.m_numConstants; - } -; - -ConstStatement: - CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } - | CONSTTOKEN ConstDeclarationList error - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } -; - -ConstDeclarationList: - ConstDeclaration { $$.m_node.head = $1.m_node; - $$.m_node.tail = $$.m_node.head; - $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, $1.m_node); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features; - $$.m_numConstants = $1.m_numConstants; - } - | ConstDeclarationList ',' ConstDeclaration - { $$.m_node.head = $1.m_node.head; - $1.m_node.tail->m_next = $3.m_node; - $$.m_node.tail = $3.m_node; - $$.m_varDeclarations = $1.m_varDeclarations; - appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, $3.m_node); - $$.m_funcDeclarations = 0; - $$.m_features = $1.m_features | $3.m_features; - $$.m_numConstants = $1.m_numConstants + $3.m_numConstants; } -; - -ConstDeclaration: - IDENT { $$ = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *$1, 0), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); } - | IDENT Initializer { $$ = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *$1, $2.m_node), ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features, $2.m_numConstants); } -; - -Initializer: - '=' AssignmentExpr { $$ = $2; } -; - -InitializerNoIn: - '=' AssignmentExprNoIn { $$ = $2; } -; - -EmptyStatement: - ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); } -; - -ExprStatement: - ExprNoBF ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } - | ExprNoBF error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } -; - -IfStatement: - IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @4); } - | IF '(' Expr ')' Statement ELSE Statement - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), - mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations), - mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations), - $3.m_features | $5.m_features | $7.m_features, - $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - setStatementLocation($$.m_node, @1, @4); } -; - -IterationStatement: - DO Statement WHILE '(' Expr ')' ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } - | DO Statement WHILE '(' Expr ')' error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. - | WHILE '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @4); } - | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations, - $3.m_features | $5.m_features | $7.m_features | $9.m_features, - $3.m_numConstants + $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - setStatementLocation($$.m_node, @1, @8); - } - | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $4.m_node, $6.m_node, $8.m_node, $10.m_node, true), - mergeDeclarationLists($4.m_varDeclarations, $10.m_varDeclarations), - mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations), - $4.m_features | $6.m_features | $8.m_features | $10.m_features, - $4.m_numConstants + $6.m_numConstants + $8.m_numConstants + $10.m_numConstants); - setStatementLocation($$.m_node, @1, @9); } - | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement - { - ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node); - setExceptionLocation(node, @3.first_column, @3.last_column, @5.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, $7.m_varDeclarations, $7.m_funcDeclarations, - $3.m_features | $5.m_features | $7.m_features, - $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - setStatementLocation($$.m_node, @1, @6); - } - | FOR '(' VAR IDENT INTOKEN Expr ')' Statement - { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column); - setExceptionLocation(forIn, @4.first_column, @5.first_column + 1, @6.last_column); - appendToVarDeclarationList(GLOBAL_DATA, $8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); - $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $6.m_features | $8.m_features, $6.m_numConstants + $8.m_numConstants); - setStatementLocation($$.m_node, @1, @7); } - | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement - { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column); - setExceptionLocation(forIn, @4.first_column, @6.first_column + 1, @7.last_column); - appendToVarDeclarationList(GLOBAL_DATA, $9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); - $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations, - ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $5.m_features | $7.m_features | $9.m_features, - $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - setStatementLocation($$.m_node, @1, @8); } -; - -ExprOpt: - /* nothing */ { $$ = createNodeInfo<ExpressionNode*>(0, 0, 0); } - | Expr -; - -ExprNoInOpt: - /* nothing */ { $$ = createNodeInfo<ExpressionNode*>(0, 0, 0); } - | ExprNoIn -; - -ContinueStatement: - CONTINUE ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); } - | CONTINUE error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } - | CONTINUE IDENT ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @3); } - | CONTINUE IDENT error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } -; - -BreakStatement: - BREAK ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } - | BREAK error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } - | BREAK IDENT ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @3); } - | BREAK IDENT error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } -; - -ReturnStatement: - RETURN ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } - | RETURN error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } - | RETURN Expr ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @3); } - | RETURN Expr error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } -; - -WithStatement: - WITH '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column), - $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features | WithFeature, $3.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @4); } -; - -SwitchStatement: - SWITCH '(' Expr ')' CaseBlock { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, - $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - setStatementLocation($$.m_node, @1, @4); } -; - -CaseBlock: - OPENBRACE CaseClausesOpt CLOSEBRACE { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, $2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); } - | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE - { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, $2.m_node.head, $3.m_node, $4.m_node.head), - mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations), - mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations), - $2.m_features | $3.m_features | $4.m_features, - $2.m_numConstants + $3.m_numConstants + $4.m_numConstants); } -; - -CaseClausesOpt: - /* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; $$.m_features = 0; $$.m_numConstants = 0; } - | CaseClauses -; - -CaseClauses: - CaseClause { $$.m_node.head = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, $1.m_node); - $$.m_node.tail = $$.m_node.head; - $$.m_varDeclarations = $1.m_varDeclarations; - $$.m_funcDeclarations = $1.m_funcDeclarations; - $$.m_features = $1.m_features; - $$.m_numConstants = $1.m_numConstants; } - | CaseClauses CaseClause { $$.m_node.head = $1.m_node.head; - $$.m_node.tail = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, $1.m_node.tail, $2.m_node); - $$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations); - $$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations); - $$.m_features = $1.m_features | $2.m_features; - $$.m_numConstants = $1.m_numConstants + $2.m_numConstants; - } -; - -CaseClause: - CASE Expr ':' { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_features, $2.m_numConstants); } - | CASE Expr ':' SourceElements { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, $2.m_node, $4.m_node), $4.m_varDeclarations, $4.m_funcDeclarations, $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); } -; - -DefaultClause: - DEFAULT ':' { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); } - | DEFAULT ':' SourceElements { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0, $3.m_node), $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); } -; - -LabelledStatement: - IDENT ':' Statement { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *$1, $3.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); } -; - -ThrowStatement: - THROW Expr ';' { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); - } - | THROW Expr error { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; - } -; - -TryStatement: - TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node), - mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations), - mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations), - $2.m_features | $4.m_features, - $2.m_numConstants + $4.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } - | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0), - mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), - mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), - $2.m_features | $7.m_features | CatchFeature, - $2.m_numConstants + $7.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } - | TRY Block CATCH '(' IDENT ')' Block FINALLY Block - { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node), - mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations), - mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations), - $2.m_features | $7.m_features | $9.m_features | CatchFeature, - $2.m_numConstants + $7.m_numConstants + $9.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } -; - -DebuggerStatement: - DEBUGGER ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); } - | DEBUGGER error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } -; - -FunctionDeclaration: - FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); setStatementLocation($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); } - | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); - if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - setStatementLocation($7, @6, @8); - $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); - } -; - -FunctionExpr: - FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); } - | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0); - if ($3.m_features & ArgumentsFeature) - $6->setUsesArguments(); - setStatementLocation($6, @5, @7); - } - | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); } - | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), $4.m_features | ClosureFeature, 0); - if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - setStatementLocation($7, @6, @8); - } -; - -FormalParameterList: - IDENT { $$.m_node.head = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, *$1); - $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; - $$.m_node.tail = $$.m_node.head; } - | FormalParameterList ',' IDENT { $$.m_node.head = $1.m_node.head; - $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); - $$.m_node.tail = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, $1.m_node.tail, *$3); } -; - -FunctionBody: - /* not in spec */ { $$ = FunctionBodyNode::create(GLOBAL_DATA); } - | SourceElements_NoNode { $$ = FunctionBodyNode::create(GLOBAL_DATA); } -; - -Program: - /* not in spec */ { GLOBAL_DATA->parser->didFinishParsing(new (GLOBAL_DATA) SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, @0.last_line, 0); } - | SourceElements { GLOBAL_DATA->parser->didFinishParsing($1.m_node, $1.m_varDeclarations, $1.m_funcDeclarations, $1.m_features, - @1.last_line, $1.m_numConstants); } -; - -SourceElements: - Statement { $$.m_node = new (GLOBAL_DATA) SourceElements(GLOBAL_DATA); - $$.m_node->append($1.m_node); - $$.m_varDeclarations = $1.m_varDeclarations; - $$.m_funcDeclarations = $1.m_funcDeclarations; - $$.m_features = $1.m_features; - $$.m_numConstants = $1.m_numConstants; - } - | SourceElements Statement { $$.m_node->append($2.m_node); - $$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations); - $$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations); - $$.m_features = $1.m_features | $2.m_features; - $$.m_numConstants = $1.m_numConstants + $2.m_numConstants; - } -; - -// Start NoNodes - -Literal_NoNode: - NULLTOKEN - | TRUETOKEN - | FALSETOKEN - | NUMBER { } - | STRING { } - | '/' /* regexp */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } - | DIVEQUAL /* regexp with /= */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } -; - -Property_NoNode: - IDENT ':' AssignmentExpr_NoNode { } - | STRING ':' AssignmentExpr_NoNode { } - | NUMBER ':' AssignmentExpr_NoNode { } - | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; } - | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; } -; - -PropertyList_NoNode: - Property_NoNode - | PropertyList_NoNode ',' Property_NoNode -; - -PrimaryExpr_NoNode: - PrimaryExprNoBrace_NoNode - | OPENBRACE CLOSEBRACE { } - | OPENBRACE PropertyList_NoNode CLOSEBRACE { } - /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */ - | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE { } -; - -PrimaryExprNoBrace_NoNode: - THISTOKEN - | Literal_NoNode - | ArrayLiteral_NoNode - | IDENT { } - | '(' Expr_NoNode ')' -; - -ArrayLiteral_NoNode: - '[' ElisionOpt_NoNode ']' - | '[' ElementList_NoNode ']' - | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']' -; - -ElementList_NoNode: - ElisionOpt_NoNode AssignmentExpr_NoNode - | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode -; - -ElisionOpt_NoNode: - /* nothing */ - | Elision_NoNode -; - -Elision_NoNode: - ',' - | Elision_NoNode ',' -; - -MemberExpr_NoNode: - PrimaryExpr_NoNode - | FunctionExpr_NoNode - | MemberExpr_NoNode '[' Expr_NoNode ']' - | MemberExpr_NoNode '.' IDENT - | NEW MemberExpr_NoNode Arguments_NoNode -; - -MemberExprNoBF_NoNode: - PrimaryExprNoBrace_NoNode - | MemberExprNoBF_NoNode '[' Expr_NoNode ']' - | MemberExprNoBF_NoNode '.' IDENT - | NEW MemberExpr_NoNode Arguments_NoNode -; - -NewExpr_NoNode: - MemberExpr_NoNode - | NEW NewExpr_NoNode -; - -NewExprNoBF_NoNode: - MemberExprNoBF_NoNode - | NEW NewExpr_NoNode -; - -CallExpr_NoNode: - MemberExpr_NoNode Arguments_NoNode - | CallExpr_NoNode Arguments_NoNode - | CallExpr_NoNode '[' Expr_NoNode ']' - | CallExpr_NoNode '.' IDENT -; - -CallExprNoBF_NoNode: - MemberExprNoBF_NoNode Arguments_NoNode - | CallExprNoBF_NoNode Arguments_NoNode - | CallExprNoBF_NoNode '[' Expr_NoNode ']' - | CallExprNoBF_NoNode '.' IDENT -; - -Arguments_NoNode: - '(' ')' - | '(' ArgumentList_NoNode ')' -; - -ArgumentList_NoNode: - AssignmentExpr_NoNode - | ArgumentList_NoNode ',' AssignmentExpr_NoNode -; - -LeftHandSideExpr_NoNode: - NewExpr_NoNode - | CallExpr_NoNode -; - -LeftHandSideExprNoBF_NoNode: - NewExprNoBF_NoNode - | CallExprNoBF_NoNode -; - -PostfixExpr_NoNode: - LeftHandSideExpr_NoNode - | LeftHandSideExpr_NoNode PLUSPLUS - | LeftHandSideExpr_NoNode MINUSMINUS -; - -PostfixExprNoBF_NoNode: - LeftHandSideExprNoBF_NoNode - | LeftHandSideExprNoBF_NoNode PLUSPLUS - | LeftHandSideExprNoBF_NoNode MINUSMINUS -; - -UnaryExprCommon_NoNode: - DELETETOKEN UnaryExpr_NoNode - | VOIDTOKEN UnaryExpr_NoNode - | TYPEOF UnaryExpr_NoNode - | PLUSPLUS UnaryExpr_NoNode - | AUTOPLUSPLUS UnaryExpr_NoNode - | MINUSMINUS UnaryExpr_NoNode - | AUTOMINUSMINUS UnaryExpr_NoNode - | '+' UnaryExpr_NoNode - | '-' UnaryExpr_NoNode - | '~' UnaryExpr_NoNode - | '!' UnaryExpr_NoNode - -UnaryExpr_NoNode: - PostfixExpr_NoNode - | UnaryExprCommon_NoNode -; - -UnaryExprNoBF_NoNode: - PostfixExprNoBF_NoNode - | UnaryExprCommon_NoNode -; - -MultiplicativeExpr_NoNode: - UnaryExpr_NoNode - | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode - | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode - | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode -; - -MultiplicativeExprNoBF_NoNode: - UnaryExprNoBF_NoNode - | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode - | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode - | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode -; - -AdditiveExpr_NoNode: - MultiplicativeExpr_NoNode - | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode - | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode -; - -AdditiveExprNoBF_NoNode: - MultiplicativeExprNoBF_NoNode - | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode - | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode -; - -ShiftExpr_NoNode: - AdditiveExpr_NoNode - | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode - | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode - | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode -; - -ShiftExprNoBF_NoNode: - AdditiveExprNoBF_NoNode - | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode - | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode - | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode -; - -RelationalExpr_NoNode: - ShiftExpr_NoNode - | RelationalExpr_NoNode '<' ShiftExpr_NoNode - | RelationalExpr_NoNode '>' ShiftExpr_NoNode - | RelationalExpr_NoNode LE ShiftExpr_NoNode - | RelationalExpr_NoNode GE ShiftExpr_NoNode - | RelationalExpr_NoNode INSTANCEOF ShiftExpr_NoNode - | RelationalExpr_NoNode INTOKEN ShiftExpr_NoNode -; - -RelationalExprNoIn_NoNode: - ShiftExpr_NoNode - | RelationalExprNoIn_NoNode '<' ShiftExpr_NoNode - | RelationalExprNoIn_NoNode '>' ShiftExpr_NoNode - | RelationalExprNoIn_NoNode LE ShiftExpr_NoNode - | RelationalExprNoIn_NoNode GE ShiftExpr_NoNode - | RelationalExprNoIn_NoNode INSTANCEOF ShiftExpr_NoNode -; - -RelationalExprNoBF_NoNode: - ShiftExprNoBF_NoNode - | RelationalExprNoBF_NoNode '<' ShiftExpr_NoNode - | RelationalExprNoBF_NoNode '>' ShiftExpr_NoNode - | RelationalExprNoBF_NoNode LE ShiftExpr_NoNode - | RelationalExprNoBF_NoNode GE ShiftExpr_NoNode - | RelationalExprNoBF_NoNode INSTANCEOF ShiftExpr_NoNode - | RelationalExprNoBF_NoNode INTOKEN ShiftExpr_NoNode -; - -EqualityExpr_NoNode: - RelationalExpr_NoNode - | EqualityExpr_NoNode EQEQ RelationalExpr_NoNode - | EqualityExpr_NoNode NE RelationalExpr_NoNode - | EqualityExpr_NoNode STREQ RelationalExpr_NoNode - | EqualityExpr_NoNode STRNEQ RelationalExpr_NoNode -; - -EqualityExprNoIn_NoNode: - RelationalExprNoIn_NoNode - | EqualityExprNoIn_NoNode EQEQ RelationalExprNoIn_NoNode - | EqualityExprNoIn_NoNode NE RelationalExprNoIn_NoNode - | EqualityExprNoIn_NoNode STREQ RelationalExprNoIn_NoNode - | EqualityExprNoIn_NoNode STRNEQ RelationalExprNoIn_NoNode -; - -EqualityExprNoBF_NoNode: - RelationalExprNoBF_NoNode - | EqualityExprNoBF_NoNode EQEQ RelationalExpr_NoNode - | EqualityExprNoBF_NoNode NE RelationalExpr_NoNode - | EqualityExprNoBF_NoNode STREQ RelationalExpr_NoNode - | EqualityExprNoBF_NoNode STRNEQ RelationalExpr_NoNode -; - -BitwiseANDExpr_NoNode: - EqualityExpr_NoNode - | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode -; - -BitwiseANDExprNoIn_NoNode: - EqualityExprNoIn_NoNode - | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode -; - -BitwiseANDExprNoBF_NoNode: - EqualityExprNoBF_NoNode - | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode -; - -BitwiseXORExpr_NoNode: - BitwiseANDExpr_NoNode - | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode -; - -BitwiseXORExprNoIn_NoNode: - BitwiseANDExprNoIn_NoNode - | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode -; - -BitwiseXORExprNoBF_NoNode: - BitwiseANDExprNoBF_NoNode - | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode -; - -BitwiseORExpr_NoNode: - BitwiseXORExpr_NoNode - | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode -; - -BitwiseORExprNoIn_NoNode: - BitwiseXORExprNoIn_NoNode - | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode -; - -BitwiseORExprNoBF_NoNode: - BitwiseXORExprNoBF_NoNode - | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode -; - -LogicalANDExpr_NoNode: - BitwiseORExpr_NoNode - | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode -; - -LogicalANDExprNoIn_NoNode: - BitwiseORExprNoIn_NoNode - | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode -; - -LogicalANDExprNoBF_NoNode: - BitwiseORExprNoBF_NoNode - | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode -; - -LogicalORExpr_NoNode: - LogicalANDExpr_NoNode - | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode -; - -LogicalORExprNoIn_NoNode: - LogicalANDExprNoIn_NoNode - | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode -; - -LogicalORExprNoBF_NoNode: - LogicalANDExprNoBF_NoNode - | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode -; - -ConditionalExpr_NoNode: - LogicalORExpr_NoNode - | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode -; - -ConditionalExprNoIn_NoNode: - LogicalORExprNoIn_NoNode - | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode -; - -ConditionalExprNoBF_NoNode: - LogicalORExprNoBF_NoNode - | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode -; - -AssignmentExpr_NoNode: - ConditionalExpr_NoNode - | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode -; - -AssignmentExprNoIn_NoNode: - ConditionalExprNoIn_NoNode - | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode -; - -AssignmentExprNoBF_NoNode: - ConditionalExprNoBF_NoNode - | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode -; - -AssignmentOperator_NoNode: - '=' - | PLUSEQUAL - | MINUSEQUAL - | MULTEQUAL - | DIVEQUAL - | LSHIFTEQUAL - | RSHIFTEQUAL - | URSHIFTEQUAL - | ANDEQUAL - | XOREQUAL - | OREQUAL - | MODEQUAL -; - -Expr_NoNode: - AssignmentExpr_NoNode - | Expr_NoNode ',' AssignmentExpr_NoNode -; - -ExprNoIn_NoNode: - AssignmentExprNoIn_NoNode - | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode -; - -ExprNoBF_NoNode: - AssignmentExprNoBF_NoNode - | ExprNoBF_NoNode ',' AssignmentExpr_NoNode -; - -Statement_NoNode: - Block_NoNode - | VariableStatement_NoNode - | ConstStatement_NoNode - | FunctionDeclaration_NoNode - | EmptyStatement_NoNode - | ExprStatement_NoNode - | IfStatement_NoNode - | IterationStatement_NoNode - | ContinueStatement_NoNode - | BreakStatement_NoNode - | ReturnStatement_NoNode - | WithStatement_NoNode - | SwitchStatement_NoNode - | LabelledStatement_NoNode - | ThrowStatement_NoNode - | TryStatement_NoNode - | DebuggerStatement_NoNode -; - -Block_NoNode: - OPENBRACE CLOSEBRACE { } - | OPENBRACE SourceElements_NoNode CLOSEBRACE { } -; - -VariableStatement_NoNode: - VAR VariableDeclarationList_NoNode ';' - | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; } -; - -VariableDeclarationList_NoNode: - IDENT { } - | IDENT Initializer_NoNode { } - | VariableDeclarationList_NoNode ',' IDENT - | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode -; - -VariableDeclarationListNoIn_NoNode: - IDENT { } - | IDENT InitializerNoIn_NoNode { } - | VariableDeclarationListNoIn_NoNode ',' IDENT - | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode -; - -ConstStatement_NoNode: - CONSTTOKEN ConstDeclarationList_NoNode ';' - | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; } -; - -ConstDeclarationList_NoNode: - ConstDeclaration_NoNode - | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode -; - -ConstDeclaration_NoNode: - IDENT { } - | IDENT Initializer_NoNode { } -; - -Initializer_NoNode: - '=' AssignmentExpr_NoNode -; - -InitializerNoIn_NoNode: - '=' AssignmentExprNoIn_NoNode -; - -EmptyStatement_NoNode: - ';' -; - -ExprStatement_NoNode: - ExprNoBF_NoNode ';' - | ExprNoBF_NoNode error { AUTO_SEMICOLON; } -; - -IfStatement_NoNode: - IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE - | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode -; - -IterationStatement_NoNode: - DO Statement_NoNode WHILE '(' Expr_NoNode ')' ';' - | DO Statement_NoNode WHILE '(' Expr_NoNode ')' error // Always performs automatic semicolon insertion - | WHILE '(' Expr_NoNode ')' Statement_NoNode - | FOR '(' ExprNoInOpt_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode - | FOR '(' VAR VariableDeclarationListNoIn_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode - | FOR '(' LeftHandSideExpr_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode - | FOR '(' VAR IDENT INTOKEN Expr_NoNode ')' Statement_NoNode - | FOR '(' VAR IDENT InitializerNoIn_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode -; - -ExprOpt_NoNode: - /* nothing */ - | Expr_NoNode -; - -ExprNoInOpt_NoNode: - /* nothing */ - | ExprNoIn_NoNode -; - -ContinueStatement_NoNode: - CONTINUE ';' - | CONTINUE error { AUTO_SEMICOLON; } - | CONTINUE IDENT ';' - | CONTINUE IDENT error { AUTO_SEMICOLON; } -; - -BreakStatement_NoNode: - BREAK ';' - | BREAK error { AUTO_SEMICOLON; } - | BREAK IDENT ';' - | BREAK IDENT error { AUTO_SEMICOLON; } -; - -ReturnStatement_NoNode: - RETURN ';' - | RETURN error { AUTO_SEMICOLON; } - | RETURN Expr_NoNode ';' - | RETURN Expr_NoNode error { AUTO_SEMICOLON; } -; - -WithStatement_NoNode: - WITH '(' Expr_NoNode ')' Statement_NoNode -; - -SwitchStatement_NoNode: - SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode -; - -CaseBlock_NoNode: - OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE { } - | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE { } -; - -CaseClausesOpt_NoNode: - /* nothing */ - | CaseClauses_NoNode -; - -CaseClauses_NoNode: - CaseClause_NoNode - | CaseClauses_NoNode CaseClause_NoNode -; - -CaseClause_NoNode: - CASE Expr_NoNode ':' - | CASE Expr_NoNode ':' SourceElements_NoNode -; - -DefaultClause_NoNode: - DEFAULT ':' - | DEFAULT ':' SourceElements_NoNode -; - -LabelledStatement_NoNode: - IDENT ':' Statement_NoNode { } -; - -ThrowStatement_NoNode: - THROW Expr_NoNode ';' - | THROW Expr_NoNode error { AUTO_SEMICOLON; } -; - -TryStatement_NoNode: - TRY Block_NoNode FINALLY Block_NoNode - | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode - | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode FINALLY Block_NoNode -; - -DebuggerStatement_NoNode: - DEBUGGER ';' - | DEBUGGER error { AUTO_SEMICOLON; } -; - -FunctionDeclaration_NoNode: - FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE - | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE -; - -FunctionExpr_NoNode: - FUNCTION '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE - | FUNCTION '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE - | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE - | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE -; - -FormalParameterList_NoNode: - IDENT { } - | FormalParameterList_NoNode ',' IDENT -; - -FunctionBody_NoNode: - /* not in spec */ - | SourceElements_NoNode -; - -SourceElements_NoNode: - Statement_NoNode - | SourceElements_NoNode Statement_NoNode -; - -// End NoNodes - -%% - -#undef GLOBAL_DATA - -static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) -{ - if (!loc->isLocation()) - return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot); - - if (loc->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(loc); - if (op == OpEqual) { - AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments); - setExceptionLocation(node, start, divot, end); - return node; - } else - return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); - } - if (loc->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); - if (op == OpEqual) - return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); - else { - ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); - node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); - return node; - } - } - ASSERT(loc->isDotAccessorNode()); - DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); - if (op == OpEqual) - return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); - - ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); - node->setSubexpressionInfo(dot->divot(), dot->endOffset()); - return node; -} - -static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) -{ - if (!expr->isLocation()) - return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot); - - if (expr->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); - } - if (expr->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); - node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); - return node; - } - ASSERT(expr->isDotAccessorNode()); - DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PrefixDotNode* node = new (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); - node->setSubexpressionInfo(dot->divot(), dot->startOffset()); - return node; -} - -static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) -{ - if (!expr->isLocation()) - return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot); - - if (expr->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); - } - if (expr->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); - node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); - return node; - - } - ASSERT(expr->isDotAccessorNode()); - DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PostfixDotNode* node = new (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); - node->setSubexpressionInfo(dot->divot(), dot->endOffset()); - return node; -} - -static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) -{ - CodeFeatures features = func.m_features | args.m_features; - int numConstants = func.m_numConstants + args.m_numConstants; - if (!func.m_node->isLocation()) - return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); - if (func.m_node->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node); - const Identifier& identifier = resolve->identifier(); - if (identifier == globalData->propertyNames->eval) - return createNodeInfo<ExpressionNode*>(new (globalData) EvalFunctionCallNode(globalData, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); - return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallResolveNode(globalData, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); - } - if (func.m_node->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node); - FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); - node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); - return createNodeInfo<ExpressionNode*>(node, features, numConstants); - } - ASSERT(func.m_node->isDotAccessorNode()); - DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node); - FunctionCallDotNode* node; - if (dot->identifier() == globalData->propertyNames->call) - node = new (globalData) CallFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - else if (dot->identifier() == globalData->propertyNames->apply) - node = new (globalData) ApplyFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - else - node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - node->setSubexpressionInfo(dot->divot(), dot->endOffset()); - return createNodeInfo<ExpressionNode*>(node, features, numConstants); -} - -static ExpressionNode* makeTypeOfNode(JSGlobalData* globalData, ExpressionNode* expr) -{ - if (expr->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) TypeOfResolveNode(globalData, resolve->identifier()); - } - return new (globalData) TypeOfValueNode(globalData, expr); -} - -static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end) -{ - if (!expr->isLocation()) - return new (globalData) DeleteValueNode(globalData, expr); - if (expr->isResolveNode()) { - ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot); - } - if (expr->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); - } - ASSERT(expr->isDotAccessorNode()); - DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); -} - -static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) -{ - PropertyNode::Type type; - if (getOrSet == "get") - type = PropertyNode::Getter; - else if (getOrSet == "set") - type = PropertyNode::Setter; - else - return 0; - return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type); -} - -static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n) -{ - if (n->isNumber()) { - NumberNode* numberNode = static_cast<NumberNode*>(n); - numberNode->setValue(-numberNode->value()); - return numberNode; - } - - return new (globalData) NegateNode(globalData, n); -} - -static NumberNode* makeNumberNode(JSGlobalData* globalData, double d) -{ - return new (globalData) NumberNode(globalData, d); -} - -static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) -{ - if (expr->isNumber()) - return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value())); - return new (globalData) BitwiseNotNode(globalData, expr); -} - -static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - expr1 = expr1->stripUnaryPlus(); - expr2 = expr2->stripUnaryPlus(); - - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); - - if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) - return new (globalData) UnaryPlusNode(globalData, expr2); - - if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) - return new (globalData) UnaryPlusNode(globalData, expr1); - - return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments); -} - -static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - expr1 = expr1->stripUnaryPlus(); - expr2 = expr2->stripUnaryPlus(); - - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); - return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments); -} - -static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); - return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments); -} - -static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - expr1 = expr1->stripUnaryPlus(); - expr2 = expr2->stripUnaryPlus(); - - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); - return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments); -} - -static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments); -} - -static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) -{ - if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments); -} - -// Called by yyparse on error. -int yyerror(const char*) -{ - return 1; -} - -// May we automatically insert a semicolon? -static bool allowAutomaticSemicolon(Lexer& lexer, int yychar) -{ - return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator(); -} - -static ExpressionNode* combineCommaNodes(JSGlobalData* globalData, ExpressionNode* list, ExpressionNode* init) -{ - if (!list) - return init; - if (list->isCommaNode()) { - static_cast<CommaNode*>(list)->append(init); - return list; - } - return new (globalData) CommaNode(globalData, list, init); -} - -// We turn variable declarations into either assignments or empty -// statements (which later get stripped out), because the actual -// declaration work is hoisted up to the start of the function body -static StatementNode* makeVarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) -{ - if (!expr) - return new (globalData) EmptyStatementNode(globalData); - return new (globalData) VarStatementNode(globalData, expr); -} diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp index 1934c0c..5825270 100644 --- a/JavaScriptCore/parser/JSParser.cpp +++ b/JavaScriptCore/parser/JSParser.cpp @@ -25,14 +25,12 @@ #include "config.h" -#if ENABLE(RECURSIVE_PARSE) #include "JSParser.h" using namespace JSC; #include "JSGlobalData.h" #include "NodeInfo.h" -#include "Grammar.h" #include "ASTBuilder.h" #include <utility> @@ -1499,6 +1497,3 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB } } - -#endif - diff --git a/JavaScriptCore/parser/JSParser.h b/JavaScriptCore/parser/JSParser.h index e212b2a..554556f 100644 --- a/JavaScriptCore/parser/JSParser.h +++ b/JavaScriptCore/parser/JSParser.h @@ -25,7 +25,6 @@ #ifndef JSParser_h #define JSParser_h -#if ENABLE(RECURSIVE_PARSE) namespace JSC { @@ -121,5 +120,4 @@ struct JSToken { int jsParse(JSGlobalData*); } -#endif #endif // JSParser_h diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp index 3a38273..660b1a4 100644 --- a/JavaScriptCore/parser/Lexer.cpp +++ b/JavaScriptCore/parser/Lexer.cpp @@ -2,6 +2,7 @@ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) + * Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -38,19 +39,178 @@ using namespace WTF; using namespace Unicode; -#if ENABLE(RECURSIVE_PARSE) #include "JSParser.h" -#else -using namespace JSC; -#include "Grammar.h" -#endif - #include "Lookup.h" #include "Lexer.lut.h" namespace JSC { -static const UChar byteOrderMark = 0xFEFF; + +enum CharacterTypes { + // Types for the main switch + CharacterInvalid, + + CharacterAlpha, + CharacterZero, + CharacterNumber, + + CharacterLineTerminator, + CharacterExclamationMark, + CharacterSimple, + CharacterQuote, + CharacterDot, + CharacterSlash, + CharacterBackSlash, + CharacterSemicolon, + CharacterOpenBrace, + CharacterCloseBrace, + + CharacterAdd, + CharacterSub, + CharacterMultiply, + CharacterModulo, + CharacterAnd, + CharacterXor, + CharacterOr, + CharacterLess, + CharacterGreater, + CharacterEqual, + + // Other types (only one so far) + CharacterWhiteSpace, +}; + +// 128 ascii codes +static unsigned char AsciiCharacters[128] = { +/* 0 - Null */ CharacterInvalid, +/* 1 - Start of Heading */ CharacterInvalid, +/* 2 - Start of Text */ CharacterInvalid, +/* 3 - End of Text */ CharacterInvalid, +/* 4 - End of Transm. */ CharacterInvalid, +/* 5 - Enquiry */ CharacterInvalid, +/* 6 - Acknowledgment */ CharacterInvalid, +/* 7 - Bell */ CharacterInvalid, +/* 8 - Back Space */ CharacterInvalid, +/* 9 - Horizontal Tab */ CharacterWhiteSpace, +/* 10 - Line Feed */ CharacterLineTerminator, +/* 11 - Vertical Tab */ CharacterWhiteSpace, +/* 12 - Form Feed */ CharacterWhiteSpace, +/* 13 - Carriage Return */ CharacterLineTerminator, +/* 14 - Shift Out */ CharacterInvalid, +/* 15 - Shift In */ CharacterInvalid, +/* 16 - Data Line Escape */ CharacterInvalid, +/* 17 - Device Control 1 */ CharacterInvalid, +/* 18 - Device Control 2 */ CharacterInvalid, +/* 19 - Device Control 3 */ CharacterInvalid, +/* 20 - Device Control 4 */ CharacterInvalid, +/* 21 - Negative Ack. */ CharacterInvalid, +/* 22 - Synchronous Idle */ CharacterInvalid, +/* 23 - End of Transmit */ CharacterInvalid, +/* 24 - Cancel */ CharacterInvalid, +/* 25 - End of Medium */ CharacterInvalid, +/* 26 - Substitute */ CharacterInvalid, +/* 27 - Escape */ CharacterInvalid, +/* 28 - File Separator */ CharacterInvalid, +/* 29 - Group Separator */ CharacterInvalid, +/* 30 - Record Separator */ CharacterInvalid, +/* 31 - Unit Separator */ CharacterInvalid, +/* 32 - Space */ CharacterWhiteSpace, +/* 33 - ! */ CharacterExclamationMark, +/* 34 - " */ CharacterQuote, +/* 35 - # */ CharacterInvalid, +/* 36 - $ */ CharacterAlpha, +/* 37 - % */ CharacterModulo, +/* 38 - & */ CharacterAnd, +/* 39 - ' */ CharacterQuote, +/* 40 - ( */ CharacterSimple, +/* 41 - ) */ CharacterSimple, +/* 42 - * */ CharacterMultiply, +/* 43 - + */ CharacterAdd, +/* 44 - , */ CharacterSimple, +/* 45 - - */ CharacterSub, +/* 46 - . */ CharacterDot, +/* 47 - / */ CharacterSlash, +/* 48 - 0 */ CharacterZero, +/* 49 - 1 */ CharacterNumber, +/* 50 - 2 */ CharacterNumber, +/* 51 - 3 */ CharacterNumber, +/* 52 - 4 */ CharacterNumber, +/* 53 - 5 */ CharacterNumber, +/* 54 - 6 */ CharacterNumber, +/* 55 - 7 */ CharacterNumber, +/* 56 - 8 */ CharacterNumber, +/* 57 - 9 */ CharacterNumber, +/* 58 - : */ CharacterSimple, +/* 59 - ; */ CharacterSemicolon, +/* 60 - < */ CharacterLess, +/* 61 - = */ CharacterEqual, +/* 62 - > */ CharacterGreater, +/* 63 - ? */ CharacterSimple, +/* 64 - @ */ CharacterInvalid, +/* 65 - A */ CharacterAlpha, +/* 66 - B */ CharacterAlpha, +/* 67 - C */ CharacterAlpha, +/* 68 - D */ CharacterAlpha, +/* 69 - E */ CharacterAlpha, +/* 70 - F */ CharacterAlpha, +/* 71 - G */ CharacterAlpha, +/* 72 - H */ CharacterAlpha, +/* 73 - I */ CharacterAlpha, +/* 74 - J */ CharacterAlpha, +/* 75 - K */ CharacterAlpha, +/* 76 - L */ CharacterAlpha, +/* 77 - M */ CharacterAlpha, +/* 78 - N */ CharacterAlpha, +/* 79 - O */ CharacterAlpha, +/* 80 - P */ CharacterAlpha, +/* 81 - Q */ CharacterAlpha, +/* 82 - R */ CharacterAlpha, +/* 83 - S */ CharacterAlpha, +/* 84 - T */ CharacterAlpha, +/* 85 - U */ CharacterAlpha, +/* 86 - V */ CharacterAlpha, +/* 87 - W */ CharacterAlpha, +/* 88 - X */ CharacterAlpha, +/* 89 - Y */ CharacterAlpha, +/* 90 - Z */ CharacterAlpha, +/* 91 - [ */ CharacterSimple, +/* 92 - \ */ CharacterBackSlash, +/* 93 - ] */ CharacterSimple, +/* 94 - ^ */ CharacterXor, +/* 95 - _ */ CharacterAlpha, +/* 96 - ` */ CharacterInvalid, +/* 97 - a */ CharacterAlpha, +/* 98 - b */ CharacterAlpha, +/* 99 - c */ CharacterAlpha, +/* 100 - d */ CharacterAlpha, +/* 101 - e */ CharacterAlpha, +/* 102 - f */ CharacterAlpha, +/* 103 - g */ CharacterAlpha, +/* 104 - h */ CharacterAlpha, +/* 105 - i */ CharacterAlpha, +/* 106 - j */ CharacterAlpha, +/* 107 - k */ CharacterAlpha, +/* 108 - l */ CharacterAlpha, +/* 109 - m */ CharacterAlpha, +/* 110 - n */ CharacterAlpha, +/* 111 - o */ CharacterAlpha, +/* 112 - p */ CharacterAlpha, +/* 113 - q */ CharacterAlpha, +/* 114 - r */ CharacterAlpha, +/* 115 - s */ CharacterAlpha, +/* 116 - t */ CharacterAlpha, +/* 117 - u */ CharacterAlpha, +/* 118 - v */ CharacterAlpha, +/* 119 - w */ CharacterAlpha, +/* 120 - x */ CharacterAlpha, +/* 121 - y */ CharacterAlpha, +/* 122 - z */ CharacterAlpha, +/* 123 - { */ CharacterOpenBrace, +/* 124 - | */ CharacterOr, +/* 125 - } */ CharacterCloseBrace, +/* 126 - ~ */ CharacterSimple, +/* 127 - Delete */ CharacterInvalid, +}; Lexer::Lexer(JSGlobalData* globalData) : m_isReparsing(false) @@ -64,77 +224,17 @@ Lexer::~Lexer() m_keywordTable.deleteTable(); } -inline const UChar* Lexer::currentCharacter() const +ALWAYS_INLINE const UChar* Lexer::currentCharacter() const { - return m_code - 4; + ASSERT(m_code <= m_codeEnd); + return m_code; } -inline int Lexer::currentOffset() const +ALWAYS_INLINE int Lexer::currentOffset() const { return currentCharacter() - m_codeStart; } -ALWAYS_INLINE void Lexer::shift1() -{ - m_current = m_next1; - m_next1 = m_next2; - m_next2 = m_next3; - if (LIKELY(m_code < m_codeEnd)) - m_next3 = m_code[0]; - else - m_next3 = -1; - - ++m_code; -} - -ALWAYS_INLINE void Lexer::shift2() -{ - m_current = m_next2; - m_next1 = m_next3; - if (LIKELY(m_code + 1 < m_codeEnd)) { - m_next2 = m_code[0]; - m_next3 = m_code[1]; - } else { - m_next2 = m_code < m_codeEnd ? m_code[0] : -1; - m_next3 = -1; - } - - m_code += 2; -} - -ALWAYS_INLINE void Lexer::shift3() -{ - m_current = m_next3; - if (LIKELY(m_code + 2 < m_codeEnd)) { - m_next1 = m_code[0]; - m_next2 = m_code[1]; - m_next3 = m_code[2]; - } else { - m_next1 = m_code < m_codeEnd ? m_code[0] : -1; - m_next2 = m_code + 1 < m_codeEnd ? m_code[1] : -1; - m_next3 = -1; - } - - m_code += 3; -} - -ALWAYS_INLINE void Lexer::shift4() -{ - if (LIKELY(m_code + 3 < m_codeEnd)) { - m_current = m_code[0]; - m_next1 = m_code[1]; - m_next2 = m_code[2]; - m_next3 = m_code[3]; - } else { - m_current = m_code < m_codeEnd ? m_code[0] : -1; - m_next1 = m_code + 1 < m_codeEnd ? m_code[1] : -1; - m_next2 = m_code + 2 < m_codeEnd ? m_code[2] : -1; - m_next3 = -1; - } - - m_code += 4; -} - void Lexer::setCode(const SourceCode& source, ParserArena& arena) { m_arena = &arena.identifierArena(); @@ -155,50 +255,58 @@ void Lexer::setCode(const SourceCode& source, ParserArena& arena) m_buffer8.reserveInitialCapacity(initialReadBufferCapacity); m_buffer16.reserveInitialCapacity((m_codeEnd - m_code) / 2); - // ECMA-262 calls for stripping all Cf characters, but we only strip BOM characters. - // See <https://bugs.webkit.org/show_bug.cgi?id=4931> for details. - if (source.provider()->hasBOMs()) { - for (const UChar* p = m_codeStart; p < m_codeEnd; ++p) { - if (UNLIKELY(*p == byteOrderMark)) { - copyCodeWithoutBOMs(); - break; - } - } - } - - // Read the first characters into the 4-character buffer. - shift4(); + if (LIKELY(m_code < m_codeEnd)) + m_current = *m_code; + else + m_current = -1; ASSERT(currentOffset() == source.startOffset()); } -void Lexer::copyCodeWithoutBOMs() +ALWAYS_INLINE void Lexer::shift() { - // Note: In this case, the character offset data for debugging will be incorrect. - // If it's important to correctly debug code with extraneous BOMs, then the caller - // should strip the BOMs when creating the SourceProvider object and do its own - // mapping of offsets within the stripped text to original text offset. - - m_codeWithoutBOMs.reserveCapacity(m_codeEnd - m_code); - for (const UChar* p = m_code; p < m_codeEnd; ++p) { - UChar c = *p; - if (c != byteOrderMark) - m_codeWithoutBOMs.append(c); - } - ptrdiff_t startDelta = m_codeStart - m_code; - m_code = m_codeWithoutBOMs.data(); - m_codeStart = m_code + startDelta; - m_codeEnd = m_codeWithoutBOMs.data() + m_codeWithoutBOMs.size(); + // Faster than an if-else sequence + ASSERT(m_current != -1); + m_current = -1; + ++m_code; + if (LIKELY(m_code < m_codeEnd)) + m_current = *m_code; +} + +ALWAYS_INLINE int Lexer::peek(int offset) +{ + // Only use if necessary + ASSERT(offset > 0 && offset < 5); + const UChar* code = m_code + offset; + return (code < m_codeEnd) ? *code : -1; +} + +int Lexer::getUnicodeCharacter() +{ + int char1 = peek(1); + int char2 = peek(2); + int char3 = peek(3); + + if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(char1) || !isASCIIHexDigit(char2) || !isASCIIHexDigit(char3))) + return -1; + + int result = convertUnicode(m_current, char1, char2, char3); + shift(); + shift(); + shift(); + shift(); + return result; } void Lexer::shiftLineTerminator() { ASSERT(isLineTerminator(m_current)); + int m_prev = m_current; + shift(); + // Allow both CRLF and LFCR. - if (m_current + m_next1 == '\n' + '\r') - shift2(); - else - shift1(); + if (m_prev + m_current == '\n' + '\r') + shift(); ++m_lineNumber; } @@ -208,7 +316,7 @@ ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, s return &m_arena->makeIdentifier(m_globalData, characters, length); } -inline bool Lexer::lastTokenWasRestrKeyword() const +ALWAYS_INLINE bool Lexer::lastTokenWasRestrKeyword() const { return m_lastToken == CONTINUE || m_lastToken == BREAK || m_lastToken == RETURN || m_lastToken == THROW; } @@ -286,11 +394,11 @@ int Lexer::lex(void* p1, void* p2) start: while (isWhiteSpace(m_current)) - shift1(); + shift(); int startOffset = currentOffset(); - if (m_current == -1) { + if (UNLIKELY(m_current == -1)) { if (!m_terminator && !m_delimited && !m_isReparsing) { // automatic semicolon insertion if program incomplete token = ';'; @@ -300,265 +408,268 @@ start: } m_delimited = false; - switch (m_current) { - case '>': - if (m_next1 == '>' && m_next2 == '>') { - if (m_next3 == '=') { - shift4(); - token = URSHIFTEQUAL; + ASSERT(m_current >= 0); + + if (m_current < 128) { + ASSERT(isASCII(m_current)); + + switch (AsciiCharacters[m_current]) { + case CharacterGreater: + shift(); + if (m_current == '>') { + shift(); + if (m_current == '>') { + shift(); + if (m_current == '=') { + shift(); + token = URSHIFTEQUAL; + break; + } + token = URSHIFT; break; } - shift3(); - token = URSHIFT; - break; - } - if (m_next1 == '>') { - if (m_next2 == '=') { - shift3(); + if (m_current == '=') { + shift(); token = RSHIFTEQUAL; break; } - shift2(); token = RSHIFT; break; } - if (m_next1 == '=') { - shift2(); + if (m_current == '=') { + shift(); token = GE; break; } - shift1(); token = '>'; break; - case '=': - if (m_next1 == '=') { - if (m_next2 == '=') { - shift3(); + case CharacterEqual: + shift(); + if (m_current == '=') { + shift(); + if (m_current == '=') { + shift(); token = STREQ; break; } - shift2(); token = EQEQ; break; } - shift1(); token = '='; break; - case '!': - if (m_next1 == '=') { - if (m_next2 == '=') { - shift3(); - token = STRNEQ; - break; - } - shift2(); - token = NE; - break; - } - shift1(); - token = '!'; - break; - case '<': - if (m_next1 == '!' && m_next2 == '-' && m_next3 == '-') { + case CharacterLess: + shift(); + if (m_current == '!' && peek(1) == '-' && peek(2) == '-') { // <!-- marks the beginning of a line comment (for www usage) - shift4(); goto inSingleLineComment; } - if (m_next1 == '<') { - if (m_next2 == '=') { - shift3(); + if (m_current == '<') { + shift(); + if (m_current == '=') { + shift(); token = LSHIFTEQUAL; break; } - shift2(); token = LSHIFT; break; } - if (m_next1 == '=') { - shift2(); + if (m_current == '=') { + shift(); token = LE; break; } - shift1(); token = '<'; break; - case '+': - if (m_next1 == '+') { - shift2(); - if (m_terminator) { - token = AUTOPLUSPLUS; + case CharacterExclamationMark: + shift(); + if (m_current == '=') { + shift(); + if (m_current == '=') { + shift(); + token = STRNEQ; break; } - token = PLUSPLUS; + token = NE; + break; + } + token = '!'; + break; + case CharacterAdd: + shift(); + if (m_current == '+') { + shift(); + token = (!m_terminator) ? PLUSPLUS : AUTOPLUSPLUS; break; } - if (m_next1 == '=') { - shift2(); + if (m_current == '=') { + shift(); token = PLUSEQUAL; break; } - shift1(); token = '+'; break; - case '-': - if (m_next1 == '-') { - if (m_atLineStart && m_next2 == '>') { - shift3(); + case CharacterSub: + shift(); + if (m_current == '-') { + shift(); + if (m_atLineStart && m_current == '>') { + shift(); goto inSingleLineComment; } - shift2(); - if (m_terminator) { - token = AUTOMINUSMINUS; - break; - } - token = MINUSMINUS; + token = (!m_terminator) ? MINUSMINUS : AUTOMINUSMINUS; break; } - if (m_next1 == '=') { - shift2(); + if (m_current == '=') { + shift(); token = MINUSEQUAL; break; } - shift1(); token = '-'; break; - case '*': - if (m_next1 == '=') { - shift2(); + case CharacterMultiply: + shift(); + if (m_current == '=') { + shift(); token = MULTEQUAL; break; } - shift1(); token = '*'; break; - case '/': - if (m_next1 == '/') { - shift2(); + case CharacterSlash: + shift(); + if (m_current == '/') { + shift(); goto inSingleLineComment; } - if (m_next1 == '*') + if (m_current == '*') { + shift(); goto inMultiLineComment; - if (m_next1 == '=') { - shift2(); + } + if (m_current == '=') { + shift(); token = DIVEQUAL; break; } - shift1(); token = '/'; break; - case '&': - if (m_next1 == '&') { - shift2(); + case CharacterAnd: + shift(); + if (m_current == '&') { + shift(); token = AND; break; } - if (m_next1 == '=') { - shift2(); + if (m_current == '=') { + shift(); token = ANDEQUAL; break; } - shift1(); token = '&'; break; - case '^': - if (m_next1 == '=') { - shift2(); + case CharacterXor: + shift(); + if (m_current == '=') { + shift(); token = XOREQUAL; break; } - shift1(); token = '^'; break; - case '%': - if (m_next1 == '=') { - shift2(); + case CharacterModulo: + shift(); + if (m_current == '=') { + shift(); token = MODEQUAL; break; } - shift1(); token = '%'; break; - case '|': - if (m_next1 == '=') { - shift2(); + case CharacterOr: + shift(); + if (m_current == '=') { + shift(); token = OREQUAL; break; } - if (m_next1 == '|') { - shift2(); + if (m_current == '|') { + shift(); token = OR; break; } - shift1(); token = '|'; break; - case '.': - if (isASCIIDigit(m_next1)) { + case CharacterDot: + shift(); + if (isASCIIDigit(m_current)) { record8('.'); - shift1(); goto inNumberAfterDecimalPoint; } token = '.'; - shift1(); break; - case ',': - case '~': - case '?': - case ':': - case '(': - case ')': - case '[': - case ']': + case CharacterSimple: token = m_current; - shift1(); + shift(); break; - case ';': - shift1(); + case CharacterSemicolon: m_delimited = true; + shift(); token = ';'; break; - case '{': + case CharacterOpenBrace: lvalp->intValue = currentOffset(); - shift1(); + shift(); token = OPENBRACE; break; - case '}': + case CharacterCloseBrace: lvalp->intValue = currentOffset(); - shift1(); m_delimited = true; + shift(); token = CLOSEBRACE; break; - case '\\': + case CharacterBackSlash: goto startIdentifierWithBackslash; - case '0': + case CharacterZero: goto startNumberWithZeroDigit; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': + case CharacterNumber: goto startNumber; - case '"': - case '\'': + case CharacterQuote: goto startString; - default: - if (isIdentStart(m_current)) - goto startIdentifierOrKeyword; - if (isLineTerminator(m_current)) { - shiftLineTerminator(); - m_atLineStart = true; - m_terminator = true; - if (lastTokenWasRestrKeyword()) { - token = ';'; - goto doneSemicolon; - } - goto start; + case CharacterAlpha: + ASSERT(isIdentStart(m_current)); + goto startIdentifierOrKeyword; + case CharacterLineTerminator: + ASSERT(isLineTerminator(m_current)); + shiftLineTerminator(); + m_atLineStart = true; + m_terminator = true; + if (lastTokenWasRestrKeyword()) { + token = ';'; + goto doneSemicolon; } + goto start; + case CharacterInvalid: goto returnError; + default: + ASSERT_NOT_REACHED(); + goto returnError; + } + } else { + // Rare characters + ASSERT(!isASCII(m_current)); + + if (isNonASCIIIdentStart(m_current)) + goto startIdentifierOrKeyword; + if (isLineTerminator(m_current)) { + shiftLineTerminator(); + m_atLineStart = true; + m_terminator = true; + if (lastTokenWasRestrKeyword()) { + token = ';'; + goto doneSemicolon; + } + goto start; + } + goto returnError; } m_atLineStart = false; @@ -566,7 +677,7 @@ start: startString: { int stringQuoteCharacter = m_current; - shift1(); + shift(); const UChar* stringStart = currentCharacter(); while (m_current != stringQuoteCharacter) { @@ -577,10 +688,10 @@ startString: { m_buffer16.append(stringStart, currentCharacter() - stringStart); goto inString; } - shift1(); + shift(); } lvalp->ident = makeIdentifier(stringStart, currentCharacter() - stringStart); - shift1(); + shift(); m_atLineStart = false; m_delimited = false; token = STRING; @@ -595,17 +706,19 @@ inString: if (UNLIKELY(m_current == -1)) goto returnError; record16(m_current); - shift1(); + shift(); } goto doneString; inStringEscapeSequence: - shift1(); + shift(); if (m_current == 'x') { - shift1(); - if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1)) { - record16(convertHex(m_current, m_next1)); - shift2(); + shift(); + if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) { + int prev = m_current; + shift(); + record16(convertHex(prev, m_current)); + shift(); goto inString; } record16('x'); @@ -614,10 +727,10 @@ inStringEscapeSequence: goto inString; } if (m_current == 'u') { - shift1(); - if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1) && isASCIIHexDigit(m_next2) && isASCIIHexDigit(m_next3)) { - record16(convertUnicode(m_current, m_next1, m_next2, m_next3)); - shift4(); + shift(); + token = getUnicodeCharacter(); + if (token != -1) { + record16(token); goto inString; } if (m_current == stringQuoteCharacter) { @@ -627,18 +740,21 @@ inStringEscapeSequence: goto returnError; } if (isASCIIOctalDigit(m_current)) { - if (m_current >= '0' && m_current <= '3' && isASCIIOctalDigit(m_next1) && isASCIIOctalDigit(m_next2)) { - record16((m_current - '0') * 64 + (m_next1 - '0') * 8 + m_next2 - '0'); - shift3(); + int char1 = m_current; + shift(); + if (char1 >= '0' && char1 <= '3' && isASCIIOctalDigit(m_current) && isASCIIOctalDigit(peek(1))) { + int char2 = m_current; + shift(); + record16((char1 - '0') * 64 + (char2 - '0') * 8 + m_current - '0'); + shift(); goto inString; } - if (isASCIIOctalDigit(m_next1)) { - record16((m_current - '0') * 8 + m_next1 - '0'); - shift2(); + if (isASCIIOctalDigit(m_current)) { + record16((char1 - '0') * 8 + m_current - '0'); + shift(); goto inString; } - record16(m_current - '0'); - shift1(); + record16(char1 - '0'); goto inString; } if (isLineTerminator(m_current)) { @@ -648,28 +764,31 @@ inStringEscapeSequence: if (m_current == -1) goto returnError; record16(singleEscape(m_current)); - shift1(); + shift(); goto inString; } -startIdentifierWithBackslash: - shift1(); +startIdentifierWithBackslash: { + shift(); if (UNLIKELY(m_current != 'u')) goto returnError; - shift1(); - if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3))) + shift(); + + token = getUnicodeCharacter(); + if (UNLIKELY(token == -1)) goto returnError; - token = convertUnicode(m_current, m_next1, m_next2, m_next3); if (UNLIKELY(!isIdentStart(token))) goto returnError; goto inIdentifierAfterCharacterCheck; +} startIdentifierOrKeyword: { const UChar* identifierStart = currentCharacter(); - shift1(); + shift(); while (isIdentPart(m_current)) - shift1(); + shift(); if (LIKELY(m_current != '\\')) { + // Fast case for idents which does not contain \uCCCC characters lvalp->ident = makeIdentifier(identifierStart, currentCharacter() - identifierStart); goto doneIdentifierOrKeyword; } @@ -677,22 +796,21 @@ startIdentifierOrKeyword: { } do { - shift1(); + shift(); if (UNLIKELY(m_current != 'u')) goto returnError; - shift1(); - if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3))) + shift(); + token = getUnicodeCharacter(); + if (UNLIKELY(token == -1)) goto returnError; - token = convertUnicode(m_current, m_next1, m_next2, m_next3); if (UNLIKELY(!isIdentPart(token))) goto returnError; inIdentifierAfterCharacterCheck: record16(token); - shift4(); while (isIdentPart(m_current)) { record16(m_current); - shift1(); + shift(); } } while (UNLIKELY(m_current == '\\')); goto doneIdentifier; @@ -701,7 +819,7 @@ inSingleLineComment: while (!isLineTerminator(m_current)) { if (UNLIKELY(m_current == -1)) return 0; - shift1(); + shift(); } shiftLineTerminator(); m_atLineStart = true; @@ -711,36 +829,43 @@ inSingleLineComment: goto start; inMultiLineComment: - shift2(); - while (m_current != '*' || m_next1 != '/') { + while (true) { + if (UNLIKELY(m_current == '*')) { + shift(); + if (m_current == '/') + break; + if (m_current == '*') + continue; + } + + if (UNLIKELY(m_current == -1)) + goto returnError; + if (isLineTerminator(m_current)) shiftLineTerminator(); - else { - shift1(); - if (UNLIKELY(m_current == -1)) - goto returnError; - } + else + shift(); } - shift2(); + shift(); m_atLineStart = false; goto start; startNumberWithZeroDigit: - shift1(); - if ((m_current | 0x20) == 'x' && isASCIIHexDigit(m_next1)) { - shift1(); + shift(); + if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) { + shift(); goto inHex; } if (m_current == '.') { record8('0'); record8('.'); - shift1(); + shift(); goto inNumberAfterDecimalPoint; } if ((m_current | 0x20) == 'e') { record8('0'); record8('e'); - shift1(); + shift(); goto inExponentIndicator; } if (isASCIIOctalDigit(m_current)) @@ -753,11 +878,11 @@ startNumberWithZeroDigit: inNumberAfterDecimalPoint: while (isASCIIDigit(m_current)) { record8(m_current); - shift1(); + shift(); } if ((m_current | 0x20) == 'e') { record8('e'); - shift1(); + shift(); goto inExponentIndicator; } goto doneNumber; @@ -765,20 +890,20 @@ inNumberAfterDecimalPoint: inExponentIndicator: if (m_current == '+' || m_current == '-') { record8(m_current); - shift1(); + shift(); } if (!isASCIIDigit(m_current)) goto returnError; do { record8(m_current); - shift1(); + shift(); } while (isASCIIDigit(m_current)); goto doneNumber; inOctal: { do { record8(m_current); - shift1(); + shift(); } while (isASCIIOctalDigit(m_current)); if (isASCIIDigit(m_current)) goto startNumber; @@ -802,7 +927,7 @@ inOctal: { inHex: { do { record8(m_current); - shift1(); + shift(); } while (isASCIIHexDigit(m_current)); double dval = 0; @@ -823,19 +948,19 @@ inHex: { startNumber: record8(m_current); - shift1(); + shift(); while (isASCIIDigit(m_current)) { record8(m_current); - shift1(); + shift(); } if (m_current == '.') { record8('.'); - shift1(); + shift(); goto inNumberAfterDecimalPoint; } if ((m_current | 0x20) == 'e') { record8('e'); - shift1(); + shift(); goto inExponentIndicator; } @@ -883,7 +1008,7 @@ doneIdentifierOrKeyword: { doneString: // Atomize constant strings in case they're later used in property lookup. - shift1(); + shift(); m_atLineStart = false; m_delimited = false; lvalp->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size()); @@ -929,7 +1054,7 @@ bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UCh return false; } - shift1(); + shift(); if (current == '/' && !lastWasEscape && !inBrackets) break; @@ -959,7 +1084,7 @@ bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UCh while (isIdentPart(m_current)) { record16(m_current); - shift1(); + shift(); } flags = makeIdentifier(m_buffer16.data(), m_buffer16.size()); @@ -979,7 +1104,7 @@ bool Lexer::skipRegExp() if (isLineTerminator(current) || current == -1) return false; - shift1(); + shift(); if (current == '/' && !lastWasEscape && !inBrackets) break; @@ -1003,7 +1128,7 @@ bool Lexer::skipRegExp() } while (isIdentPart(m_current)) - shift1(); + shift(); return true; } @@ -1024,26 +1149,6 @@ void Lexer::clear() SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine) { - if (m_codeWithoutBOMs.isEmpty()) - return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine); - - const UChar* data = m_source->provider()->data(); - - ASSERT(openBrace < closeBrace); - int i; - for (i = m_source->startOffset(); i < openBrace; ++i) { - if (data[i] == byteOrderMark) { - openBrace++; - closeBrace++; - } - } - for (; i < closeBrace; ++i) { - if (data[i] == byteOrderMark) - closeBrace++; - } - - ASSERT(openBrace < closeBrace); - return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine); } diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h index f197093..ec254ce 100644 --- a/JavaScriptCore/parser/Lexer.h +++ b/JavaScriptCore/parser/Lexer.h @@ -1,6 +1,7 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,6 +27,7 @@ #include "ParserArena.h" #include "SourceCode.h" #include <wtf/ASCIICType.h> +#include <wtf/AlwaysInline.h> #include <wtf/SegmentedVector.h> #include <wtf/Vector.h> #include <wtf/unicode/Unicode.h> @@ -66,24 +68,23 @@ namespace JSC { Lexer(JSGlobalData*); ~Lexer(); - void shift1(); - void shift2(); - void shift3(); - void shift4(); - void shiftLineTerminator(); - void record8(int); void record16(int); void record16(UChar); void copyCodeWithoutBOMs(); - int currentOffset() const; - const UChar* currentCharacter() const; + ALWAYS_INLINE void shift(); + ALWAYS_INLINE int peek(int offset); + int getUnicodeCharacter(); + void shiftLineTerminator(); + + ALWAYS_INLINE const UChar* currentCharacter() const; + ALWAYS_INLINE int currentOffset() const; - const Identifier* makeIdentifier(const UChar* characters, size_t length); + ALWAYS_INLINE const Identifier* makeIdentifier(const UChar* characters, size_t length); - bool lastTokenWasRestrKeyword() const; + ALWAYS_INLINE bool lastTokenWasRestrKeyword() const; static const size_t initialReadBufferCapacity = 32; @@ -106,10 +107,7 @@ namespace JSC { // current and following unicode characters (int to allow for -1 for end-of-file marker) int m_current; - int m_next1; - int m_next2; - int m_next3; - + IdentifierArena* m_arena; JSGlobalData* m_globalData; diff --git a/JavaScriptCore/parser/NodeConstructors.h b/JavaScriptCore/parser/NodeConstructors.h index 8b64e0f..4e094b6 100644 --- a/JavaScriptCore/parser/NodeConstructors.h +++ b/JavaScriptCore/parser/NodeConstructors.h @@ -43,11 +43,7 @@ namespace JSC { } inline Node::Node(JSGlobalData* globalData) -#if ENABLE(RECURSIVE_PARSE) : m_line(globalData->lexer->lastLineNumber()) -#else - : m_line(globalData->lexer->lineNumber()) -#endif { } diff --git a/JavaScriptCore/parser/Parser.cpp b/JavaScriptCore/parser/Parser.cpp index fe92b40..b97754f 100644 --- a/JavaScriptCore/parser/Parser.cpp +++ b/JavaScriptCore/parser/Parser.cpp @@ -59,12 +59,8 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg) Lexer& lexer = *globalData->lexer; lexer.setCode(*m_source, m_arena); - -#if ENABLE(RECURSIVE_PARSE) + int parseError = jsParse(globalData); -#else - int parseError = jscyyparse(globalData); -#endif int lineNumber = lexer.lineNumber(); bool lexError = lexer.sawError(); lexer.clear(); diff --git a/JavaScriptCore/parser/SourceProvider.h b/JavaScriptCore/parser/SourceProvider.h index 1c59eed..87ea960 100644 --- a/JavaScriptCore/parser/SourceProvider.h +++ b/JavaScriptCore/parser/SourceProvider.h @@ -34,13 +34,10 @@ namespace JSC { - enum SourceBOMPresence { SourceHasNoBOMs, SourceCouldHaveBOMs }; - class SourceProvider : public RefCounted<SourceProvider> { public: - SourceProvider(const UString& url, SourceBOMPresence hasBOMs = SourceCouldHaveBOMs) + SourceProvider(const UString& url) : m_url(url) - , m_hasBOMs(hasBOMs) { } virtual ~SourceProvider() { } @@ -52,29 +49,33 @@ namespace JSC { const UString& url() { return m_url; } intptr_t asID() { return reinterpret_cast<intptr_t>(this); } - SourceBOMPresence hasBOMs() const { return m_hasBOMs; } - private: UString m_url; - SourceBOMPresence m_hasBOMs; }; class UStringSourceProvider : public SourceProvider { public: - static PassRefPtr<UStringSourceProvider> create(const UString& source, const UString& url) + static PassRefPtr<UStringSourceProvider> create(const UString& source, const UString& url, bool hasBOMs = true) { - return adoptRef(new UStringSourceProvider(source, url)); + return adoptRef(new UStringSourceProvider(source, url, hasBOMs)); } - UString getRange(int start, int end) const { return m_source.substr(start, end - start); } + UString getRange(int start, int end) const + { + return m_source.substr(start, end - start); + } const UChar* data() const { return m_source.data(); } int length() const { return m_source.size(); } private: - UStringSourceProvider(const UString& source, const UString& url) + UStringSourceProvider(const UString& source, const UString& url, bool hasBOMs) : SourceProvider(url) , m_source(source) { + if (hasBOMs && m_source.size()) { + bool scratch = false; + m_source = UString(m_source.rep()->copyStringWithoutBOMs(false, scratch)); + } } UString m_source; diff --git a/JavaScriptCore/pcre/pcre_compile.cpp b/JavaScriptCore/pcre/pcre_compile.cpp index 2bedca6..ea6e44c 100644 --- a/JavaScriptCore/pcre/pcre_compile.cpp +++ b/JavaScriptCore/pcre/pcre_compile.cpp @@ -48,6 +48,7 @@ supporting internal functions that are not used by other modules. */ #include <string.h> #include <wtf/ASCIICType.h> #include <wtf/FastMalloc.h> +#include <wtf/FixedArray.h> using namespace WTF; @@ -2035,8 +2036,8 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt int branch_extra = 0; int lastitemlength = 0; unsigned brastackptr = 0; - int brastack[BRASTACK_SIZE]; - unsigned char bralenstack[BRASTACK_SIZE]; + FixedArray<int, BRASTACK_SIZE> brastack; + FixedArray<unsigned char, BRASTACK_SIZE> bralenstack; int bracount = 0; const UChar* ptr = (const UChar*)(pattern - 1); diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog new file mode 100644 index 0000000..8f2d423 --- /dev/null +++ b/JavaScriptCore/qt/ChangeLog @@ -0,0 +1,59 @@ +2010-07-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Compilation fix. + + QScriptEnginePrivate::newArray can't be const because it can + throw an exception. + + [Qt] QScriptEnginePrivate compilation fix + https://bugs.webkit.org/show_bug.cgi?id=41520 + + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::newArray): + * api/qscriptengine_p.h: + +2010-06-28 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Implement exception reporting in the QtScript API. + + The exception should be accessible through the API by the uncaughtException + function. Functions; hasUncaughtException, clearExceptions, uncaughtExceptionLineNumber, + uncaughtExceptionBacktrace were added to facilitate error checking and debugging. + + [Qt] QtScript API should be exceptions aware. + https://bugs.webkit.org/show_bug.cgi?id=41199 + + * api/qscriptengine.cpp: + (QScriptEngine::hasUncaughtException): + (QScriptEngine::uncaughtException): + (QScriptEngine::clearExceptions): + (QScriptEngine::uncaughtExceptionLineNumber): + (QScriptEngine::uncaughtExceptionBacktrace): + * api/qscriptengine.h: + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + (QScriptEnginePrivate::uncaughtException): + * api/qscriptengine_p.h: + (QScriptEnginePrivate::): + (QScriptEnginePrivate::evaluate): + (QScriptEnginePrivate::hasUncaughtException): + (QScriptEnginePrivate::clearExceptions): + (QScriptEnginePrivate::setException): + (QScriptEnginePrivate::uncaughtExceptionLineNumber): + (QScriptEnginePrivate::uncaughtExceptionBacktrace): + * api/qscriptvalue_p.h: + (QScriptValuePrivate::toString): + (QScriptValuePrivate::toNumber): + (QScriptValuePrivate::toObject): + (QScriptValuePrivate::equals): + (QScriptValuePrivate::instanceOf): + (QScriptValuePrivate::call): + (QScriptValuePrivate::inherits): + * tests/qscriptengine/tst_qscriptengine.cpp: + (tst_QScriptEngine::uncaughtException): + diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp index e1bdf77..4b2319b 100644 --- a/JavaScriptCore/qt/api/qscriptengine.cpp +++ b/JavaScriptCore/qt/api/qscriptengine.cpp @@ -96,6 +96,71 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram& program) } /*! + Returns true if the last script evaluation resulted in an uncaught + exception; otherwise returns false. + + The exception state is cleared when evaluate() is called. + + \sa uncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +bool QScriptEngine::hasUncaughtException() const +{ + return d_ptr->hasUncaughtException(); +} + +/*! + Returns the current uncaught exception, or an invalid QScriptValue + if there is no uncaught exception. + + The exception value is typically an \c{Error} object; in that case, + you can call toString() on the return value to obtain an error + message. + + \sa hasUncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +QScriptValue QScriptEngine::uncaughtException() const +{ + return QScriptValuePrivate::get(d_ptr->uncaughtException()); +} + +/*! + Clears any uncaught exceptions in this engine. + + \sa hasUncaughtException() +*/ +void QScriptEngine::clearExceptions() +{ + d_ptr->clearExceptions(); +} + +/*! + Returns the line number where the last uncaught exception occurred. + + Line numbers are 1-based, unless a different base was specified as + the second argument to evaluate(). + + \sa hasUncaughtException(), uncaughtExceptionBacktrace() +*/ +int QScriptEngine::uncaughtExceptionLineNumber() const +{ + return d_ptr->uncaughtExceptionLineNumber(); +} + +/*! + Returns a human-readable backtrace of the last uncaught exception. + + Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. + + \sa uncaughtException() +*/ +QStringList QScriptEngine::uncaughtExceptionBacktrace() const +{ + return d_ptr->uncaughtExceptionBacktrace(); +} + +/*! Runs the garbage collector. The garbage collector will attempt to reclaim memory by locating and disposing of objects that are @@ -206,6 +271,16 @@ QScriptValue QScriptEngine::newObject() } /*! + Creates a QtScript object of class Array with the given \a length. + + \sa newObject() +*/ +QScriptValue QScriptEngine::newArray(uint length) +{ + return QScriptValuePrivate::get(d_ptr->newArray(length)); +} + +/*! Returns this engine's Global Object. By default, the Global Object contains the built-in objects that are diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h index 653dffe..1a87a37 100644 --- a/JavaScriptCore/qt/api/qscriptengine.h +++ b/JavaScriptCore/qt/api/qscriptengine.h @@ -42,6 +42,12 @@ public: QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); QScriptValue evaluate(const QScriptProgram& program); + bool hasUncaughtException() const; + QScriptValue uncaughtException() const; + void clearExceptions(); + int uncaughtExceptionLineNumber() const; + QStringList uncaughtExceptionBacktrace() const; + void collectGarbage(); void reportAdditionalMemoryCost(int cost); @@ -51,6 +57,7 @@ public: QScriptValue nullValue(); QScriptValue undefinedValue(); QScriptValue newObject(); + QScriptValue newArray(uint length = 0); QScriptValue globalObject() const; private: friend class QScriptEnginePrivate; diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp index fd7978b..23e41c4 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.cpp +++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -31,11 +31,14 @@ QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine) : q_ptr(const_cast<QScriptEngine*>(engine)) , m_context(JSGlobalContextCreate(0)) + , m_exception(0) { } QScriptEnginePrivate::~QScriptEnginePrivate() { + if (m_exception) + JSValueUnprotect(m_context, m_exception); JSGlobalContextRelease(m_context); } @@ -77,11 +80,35 @@ QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QScriptProgramPrivate* return new QScriptValuePrivate(this, evaluate(*program, program->file(), program->line())); } +QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const +{ + return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate(); +} + QScriptValuePrivate* QScriptEnginePrivate::newObject() const { return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0)); } +QScriptValuePrivate* QScriptEnginePrivate::newArray(uint length) +{ + JSValueRef exception = 0; + JSObjectRef array = JSObjectMakeArray(m_context, /* argumentCount */ 0, /* arguments */ 0, &exception); + + if (!exception) { + if (length > 0) { + JSRetainPtr<JSStringRef> lengthRef(Adopt, JSStringCreateWithUTF8CString("length")); + // array is an Array instance, so an exception should not occure here. + JSObjectSetProperty(m_context, array, lengthRef.get(), JSValueMakeNumber(m_context, length), kJSPropertyAttributeNone, /* exception */ 0); + } + } else { + setException(exception, NotNullException); + return new QScriptValuePrivate(); + } + + return new QScriptValuePrivate(this, array); +} + QScriptValuePrivate* QScriptEnginePrivate::globalObject() const { JSObjectRef globalObject = JSContextGetGlobalObject(m_context); diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h index 9083f7d..30ee039 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.h +++ b/JavaScriptCore/qt/api/qscriptengine_p.h @@ -26,9 +26,11 @@ #include "qscriptsyntaxcheckresult_p.h" #include "qscriptvalue.h" #include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> #include <JSBasePrivate.h> #include <QtCore/qshareddata.h> #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> class QScriptEngine; class QScriptSyntaxCheckResultPrivate; @@ -41,11 +43,23 @@ public: QScriptEnginePrivate(const QScriptEngine*); ~QScriptEnginePrivate(); + enum SetExceptionFlag { + IgnoreNullException = 0x01, + NotNullException = 0x02, + }; + QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program); QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber); QScriptValuePrivate* evaluate(const QScriptProgramPrivate* program); inline JSValueRef evaluate(JSStringRef program, JSStringRef fileName, int lineNumber); + inline bool hasUncaughtException() const; + QScriptValuePrivate* uncaughtException() const; + inline void clearExceptions(); + inline void setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags = IgnoreNullException); + inline int uncaughtExceptionLineNumber() const; + inline QStringList uncaughtExceptionBacktrace() const; + inline void collectGarbage(); inline void reportAdditionalMemoryCost(int cost); @@ -57,6 +71,7 @@ public: inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const; QScriptValuePrivate* newObject() const; + QScriptValuePrivate* newArray(uint length); QScriptValuePrivate* globalObject() const; inline QScriptStringPrivate* toStringHandle(const QString& str) const; @@ -65,6 +80,7 @@ public: private: QScriptEngine* q_ptr; JSGlobalContextRef m_context; + JSValueRef m_exception; }; @@ -77,11 +93,67 @@ JSValueRef QScriptEnginePrivate::evaluate(JSStringRef program, JSStringRef fileN { JSValueRef exception; JSValueRef result = JSEvaluateScript(m_context, program, /* Global Object */ 0, fileName, lineNumber, &exception); - if (!result) + if (!result) { + setException(exception, NotNullException); return exception; // returns an exception + } + clearExceptions(); return result; } +bool QScriptEnginePrivate::hasUncaughtException() const +{ + return m_exception; +} + +void QScriptEnginePrivate::clearExceptions() +{ + if (m_exception) + JSValueUnprotect(m_context, m_exception); + m_exception = 0; +} + +void QScriptEnginePrivate::setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags) +{ + if (!((flags & NotNullException) || exception)) + return; + Q_ASSERT(exception); + + if (m_exception) + JSValueUnprotect(m_context, m_exception); + JSValueProtect(m_context, exception); + m_exception = exception; +} + +int QScriptEnginePrivate::uncaughtExceptionLineNumber() const +{ + if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception)) + return -1; + + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line")); + JSValueRef lineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception); + int result = JSValueToNumber(m_context, lineNumber, &exception); + return exception ? -1 : result; +} + +QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const +{ + if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception)) + return QStringList(); + + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> fileNamePropertyName(Adopt, QScriptConverter::toString("sourceURL")); + JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line")); + JSValueRef jsFileName = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), fileNamePropertyName.get(), &exception); + JSValueRef jsLineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception); + JSRetainPtr<JSStringRef> fileName(Adopt, JSValueToStringCopy(m_context, jsFileName, &exception)); + int lineNumber = JSValueToNumber(m_context, jsLineNumber, &exception); + return QStringList(QString::fromLatin1("<anonymous>()@%0:%1") + .arg(QScriptConverter::toString(fileName.get())) + .arg(QScriptConverter::toString(exception ? -1 : lineNumber))); +} + void QScriptEnginePrivate::collectGarbage() { JSGarbageCollect(m_context); diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp index 8ad76a5..e309fb7 100644 --- a/JavaScriptCore/qt/api/qscriptvalue.cpp +++ b/JavaScriptCore/qt/api/qscriptvalue.cpp @@ -627,3 +627,41 @@ bool QScriptValue::instanceOf(const QScriptValue& other) const { return d_ptr->instanceOf(QScriptValuePrivate::get(other)); } + +/*! + Returns the value of this QScriptValue's property with the given \a name, + using the given \a mode to resolve the property. + + If no such property exists, an invalid QScriptValue is returned. + + If the property is implemented using a getter function (i.e. has the + PropertyGetter flag set), calling property() has side-effects on the + script engine, since the getter function will be called (possibly + resulting in an uncaught script exception). If an exception + occurred, property() returns the value that was thrown (typically + an \c{Error} object). + + \sa setProperty(), propertyFlags(), QScriptValueIterator +*/ +QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const +{ + return QScriptValuePrivate::get(d_ptr->property(name, mode)); +} + +/*! + \overload + + Returns the property at the given \a arrayIndex, using the given \a + mode to resolve the property. + + This function is provided for convenience and performance when + working with array objects. + + If this QScriptValue is not an Array object, this function behaves + as if property() was called with the string representation of \a + arrayIndex. +*/ +QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const +{ + return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode)); +} diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h index c82ef55..c55d461 100644 --- a/JavaScriptCore/qt/api/qscriptvalue.h +++ b/JavaScriptCore/qt/api/qscriptvalue.h @@ -32,7 +32,14 @@ typedef QList<QScriptValue> QScriptValueList; typedef double qsreal; class QScriptValue { -public: +public: + enum ResolveFlag { + ResolveLocal = 0x00, + ResolvePrototype = 0x01 + }; + + Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag) + enum SpecialValue { NullValue, UndefinedValue @@ -67,6 +74,9 @@ public: bool strictlyEquals(const QScriptValue& other) const; bool instanceOf(const QScriptValue& other) const; + QScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const; + QScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const; + QScriptEngine* engine() const; bool isValid() const; diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h index f8a1e7a..49bec97 100644 --- a/JavaScriptCore/qt/api/qscriptvalue_p.h +++ b/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -120,6 +120,9 @@ public: inline bool instanceOf(QScriptValuePrivate* other); inline bool assignEngine(QScriptEnginePrivate* engine); + inline QScriptValuePrivate* property(const QString& name, const QScriptValue::ResolveFlags& mode); + inline QScriptValuePrivate* property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode); + inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args); inline operator JSValueRef() const; @@ -442,7 +445,9 @@ QString QScriptValuePrivate::toString() const case JSValue: case JSPrimitive: case JSObject: - JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, /* exception */ 0)); + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, &exception)); + m_engine->setException(exception); return QScriptConverter::toString(ptr.get()); } @@ -456,7 +461,12 @@ qsreal QScriptValuePrivate::toNumber() const case JSValue: case JSPrimitive: case JSObject: - return JSValueToNumber(*m_engine, *this, /* exception */ 0); + { + JSValueRef exception = 0; + qsreal result = JSValueToNumber(*m_engine, *this, &exception); + m_engine->setException(exception); + return result; + } case CNumber: return u.m_number; case CBool: @@ -585,9 +595,13 @@ QScriptValuePrivate* QScriptValuePrivate::toObject(QScriptEnginePrivate* engine) { if (engine != this->engine()) qWarning("QScriptEngine::toObject: cannot convert value created in a different engine"); - JSObjectRef object = JSValueToObject(*m_engine, *this, /* exception */ 0); + JSValueRef exception = 0; + JSObjectRef object = JSValueToObject(*m_engine, *this, &exception); if (object) return new QScriptValuePrivate(m_engine.constData(), object); + else + m_engine->setException(exception, QScriptEnginePrivate::NotNullException); + } return new QScriptValuePrivate; case JSObject: @@ -621,7 +635,7 @@ inline QScriptValuePrivate* QScriptValuePrivate::prototype() return new QScriptValuePrivate(engine(), prototype); // The prototype could be either a null or a JSObject, so it is safe to cast the prototype // to the JSObjectRef here. - return new QScriptValuePrivate(engine(), prototype, const_cast<JSObjectRef>(prototype)); + return new QScriptValuePrivate(engine(), const_cast<JSObjectRef>(prototype)); } return new QScriptValuePrivate; } @@ -672,7 +686,10 @@ bool QScriptValuePrivate::equals(QScriptValuePrivate* other) } } - return JSValueIsEqual(*m_engine, *this, *other, /* exception */ 0); + JSValueRef exception = 0; + bool result = JSValueIsEqual(*m_engine, *this, *other, &exception); + m_engine->setException(exception); + return result; } bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other) @@ -716,7 +733,10 @@ inline bool QScriptValuePrivate::instanceOf(QScriptValuePrivate* other) { if (!isJSBased() || !other->isObject()) return false; - return JSValueIsInstanceOfConstructor(*m_engine, *this, *other, /* exception */ 0); + JSValueRef exception = 0; + bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, *other, &exception); + m_engine->setException(exception); + return result; } /*! @@ -756,6 +776,35 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine) return true; } +inline QScriptValuePrivate* QScriptValuePrivate::property(const QString& name, const QScriptValue::ResolveFlags& mode) +{ + if (!isObject()) + return new QScriptValuePrivate; + + if (mode & QScriptValue::ResolveLocal) { + qWarning("QScriptValue::property(): ResolveLocal not supported yet."); + return new QScriptValuePrivate; + } + + JSRetainPtr<JSStringRef> nameRef(Adopt, QScriptConverter::toString(name)); + QScriptValuePrivate* result = new QScriptValuePrivate(m_engine.constData(), JSObjectGetProperty(*m_engine, *this, nameRef.get(), /* exception */ 0)); + + return result; +} + +inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode) +{ + if (!isObject()) + return new QScriptValuePrivate; + + if (mode & QScriptValue::ResolveLocal) { + qWarning("QScriptValue::property(): ResolveLocal not supported yet."); + return new QScriptValuePrivate; + } + + return new QScriptValuePrivate(m_engine.constData(), JSObjectGetPropertyAtIndex(*m_engine, *this, arrayIndex, /* exception */ 0)); +} + QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args) { switch (m_state) { @@ -781,8 +830,10 @@ QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const // Make the call JSValueRef exception = 0; JSValueRef result = JSObjectCallAsFunction(*m_engine, *this, /* thisObject */ 0, argc, argv.constData(), &exception); - if (!result && exception) + if (!result && exception) { + m_engine->setException(exception); return new QScriptValuePrivate(engine(), exception); + } if (result && !exception) return new QScriptValuePrivate(engine(), result); } @@ -823,9 +874,12 @@ bool QScriptValuePrivate::inherits(const char* name) Q_ASSERT(isJSBased()); JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine); JSStringRef errorAttrName = QScriptConverter::toString(name); - JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, /* exception */ 0); + JSValueRef exception = 0; + JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, &exception); JSStringRelease(errorAttrName); - return JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, /* exception */ 0), /* exception */ 0); + bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, &exception), &exception); + m_engine->setException(exception); + return result; } /*! diff --git a/JavaScriptCore/qt/benchmarks/benchmarks.pri b/JavaScriptCore/qt/benchmarks/benchmarks.pri new file mode 100644 index 0000000..5af3383 --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/benchmarks.pri @@ -0,0 +1,19 @@ +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR +mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) { + LIBS += -framework QtScript + QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH +} else { + win32-*|wince* { + LIBS += -lQtScript$${QT_MAJOR_VERSION} + } else { + LIBS += -lQtScript + } +} + +CONFIG(release, debug|release) { + DEFINES += NDEBUG +} + +INCLUDEPATH += $$PWD/../api + diff --git a/JavaScriptCore/qt/benchmarks/benchmarks.pro b/JavaScriptCore/qt/benchmarks/benchmarks.pro new file mode 100644 index 0000000..85fa82c --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/benchmarks.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = qscriptengine \ + qscriptvalue \ + diff --git a/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro b/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro new file mode 100644 index 0000000..e94137d --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = tst_bench_qscriptengine + +SOURCES += tst_qscriptengine.cpp + +QT += testlib + +include(../benchmarks.pri) + +symbian* { + TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB + TARGET.EPOCSTACKSIZE = 0x14000 +} diff --git a/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp new file mode 100644 index 0000000..0c447c6 --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp @@ -0,0 +1,142 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + 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 "qscriptengine.h" +#include "qscriptvalue.h" +#include <qtest.h> + +class tst_QScriptEngine : public QObject { + Q_OBJECT + +private slots: + void checkSyntax_data(); + void checkSyntax(); + void constructor(); + void evaluateString_data(); + void evaluateString(); + void evaluateProgram_data(); + void evaluateProgram(); + void newObject(); + void nullValue(); + void undefinedValue(); + void globalObject(); + void toStringHandle(); +}; + +void tst_QScriptEngine::checkSyntax_data() +{ + evaluateString_data(); +} + +void tst_QScriptEngine::checkSyntax() +{ + QFETCH(QString, code); + QScriptEngine engine; + QBENCHMARK { + engine.checkSyntax(code); + } +} + +void tst_QScriptEngine::constructor() +{ + QBENCHMARK { + QScriptEngine engine; + } +} + +void tst_QScriptEngine::evaluateString_data() +{ + QTest::addColumn<QString>("code"); + QTest::newRow("empty script") << QString::fromLatin1(""); + QTest::newRow("number literal") << QString::fromLatin1("123"); + QTest::newRow("string literal") << QString::fromLatin1("'ciao'"); + QTest::newRow("regexp literal") << QString::fromLatin1("/foo/gim"); + QTest::newRow("null literal") << QString::fromLatin1("null"); + QTest::newRow("undefined literal") << QString::fromLatin1("undefined"); + QTest::newRow("empty object literal") << QString::fromLatin1("{}"); + QTest::newRow("this") << QString::fromLatin1("this"); +} + +void tst_QScriptEngine::evaluateString() +{ + QFETCH(QString, code); + QScriptEngine engine; + QBENCHMARK { + engine.evaluate(code); + } +} + +void tst_QScriptEngine::evaluateProgram_data() +{ + evaluateString_data(); +} + +void tst_QScriptEngine::evaluateProgram() +{ + QFETCH(QString, code); + QScriptEngine engine; + QScriptProgram program(code); + QBENCHMARK { + engine.evaluate(program); + } +} + +void tst_QScriptEngine::newObject() +{ + QScriptEngine engine; + QBENCHMARK { + engine.newObject(); + } +} + +void tst_QScriptEngine::nullValue() +{ + QScriptEngine engine; + QBENCHMARK { + engine.nullValue(); + } +} + +void tst_QScriptEngine::undefinedValue() +{ + QScriptEngine engine; + QBENCHMARK { + engine.undefinedValue(); + } +} + +void tst_QScriptEngine::globalObject() +{ + QScriptEngine engine; + QBENCHMARK { + engine.globalObject(); + } +} + +void tst_QScriptEngine::toStringHandle() +{ + QScriptEngine engine; + QString str = QString::fromLatin1("foobarbaz"); + QBENCHMARK { + engine.toStringHandle(str); + } +} + +QTEST_MAIN(tst_QScriptEngine) +#include "tst_qscriptengine.moc" diff --git a/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro b/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro new file mode 100644 index 0000000..673fe65 --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = tst_bench_qscriptvalue +QT += testlib + +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../.. +include(../benchmarks.pri) + +SOURCES += tst_qscriptvalue.cpp + diff --git a/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp new file mode 100644 index 0000000..7c39b8e --- /dev/null +++ b/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp @@ -0,0 +1,442 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + 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 "qscriptengine.h" +#include "qscriptstring.h" +#include "qscriptvalue.h" +#include <qtest.h> + +Q_DECLARE_METATYPE(QScriptValue); + +class tst_QScriptValue : public QObject { + Q_OBJECT + +public: + tst_QScriptValue() + : m_engine(0) + {} + + ~tst_QScriptValue() + { + if (m_engine) + delete m_engine; + } + +private slots: + void values_data(); + + void ctorBool(); + void ctorReal(); + void ctorNumber(); + void ctorQString(); + void ctorCString(); + void ctorSpecial(); + void ctorQScriptValue(); + + void isValid_data(); + void isValid(); + void isBool_data(); + void isBool(); + void isNumber_data(); + void isNumber(); + void isFunction_data(); + void isFunction(); + void isNull_data(); + void isNull(); + void isString_data(); + void isString(); + void isUndefined_data(); + void isUndefined(); + void isObject_data(); + void isObject(); + void isError_data(); + void isError(); + + void toString_data(); + void toString(); + void toNumber_data(); + void toNumber(); + void toBool_data(); + void toBool(); + void toInteger_data(); + void toInteger(); + void toInt32_data(); + void toInt32(); + void toUInt32_data(); + void toUInt32(); + void toUInt16_data(); + void toUInt16(); + void toObject_data(); + void toObject(); + + void equals_data(); + void equals(); + void strictlyEquals_data(); + void strictlyEquals(); + void instanceOf_data(); + void instanceOf(); + +private: + QScriptEngine* m_engine; +}; + +void tst_QScriptValue::values_data() +{ + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine; + + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + + QTest::newRow("cbool") << QScriptValue(true); + QTest::newRow("cnumber") << QScriptValue(1234); + QTest::newRow("cstring") << QScriptValue("abc"); + QTest::newRow("cnull") << QScriptValue(QScriptValue::NullValue); + QTest::newRow("cundefined") << QScriptValue(QScriptValue::UndefinedValue); + + QTest::newRow("jsbool") << m_engine->evaluate("true"); + QTest::newRow("jsnumber") << m_engine->evaluate("12345"); + QTest::newRow("jsstring") << m_engine->evaluate("'go'"); + QTest::newRow("jsfunction") << m_engine->evaluate("(function {})"); + QTest::newRow("jsnull") << m_engine->nullValue(); + QTest::newRow("jsundefined") << m_engine->undefinedValue(); + QTest::newRow("jsobject") << m_engine->newObject(); + QTest::newRow("jserror") << m_engine->evaluate("new Error()"); +} + +void tst_QScriptValue::ctorBool() +{ + QBENCHMARK { + QScriptValue(true); + } +} + +void tst_QScriptValue::ctorReal() +{ + QBENCHMARK { + QScriptValue(12.3); + } +} + +void tst_QScriptValue::ctorNumber() +{ + QBENCHMARK { + QScriptValue(123); + } +} + +void tst_QScriptValue::ctorQString() +{ + QString str = QString::fromLatin1("ciao"); + QBENCHMARK { + QScriptValue(str); + } +} + +void tst_QScriptValue::ctorCString() +{ + QBENCHMARK { + QScriptValue("Pong!"); + } +} + +void tst_QScriptValue::ctorSpecial() +{ + QBENCHMARK { + (void)QScriptValue(QScriptValue::NullValue); + } +} + +void tst_QScriptValue::ctorQScriptValue() +{ + QScriptValue tmp(1234); + QBENCHMARK { + QScriptValue(tmp); + } +} + +void tst_QScriptValue::isValid_data() +{ + values_data(); +} + +void tst_QScriptValue::isValid() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isValid(); + } +} + +void tst_QScriptValue::isBool_data() +{ + values_data(); +} + +void tst_QScriptValue::isBool() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isBool(); + } +} + +void tst_QScriptValue::isNumber_data() +{ + values_data(); +} + +void tst_QScriptValue::isNumber() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isNumber(); + } +} + +void tst_QScriptValue::isFunction_data() +{ + values_data(); +} + +void tst_QScriptValue::isFunction() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isFunction(); + } +} + +void tst_QScriptValue::isNull_data() +{ + values_data(); +} + +void tst_QScriptValue::isNull() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isNull(); + } +} + +void tst_QScriptValue::isString_data() +{ + values_data(); +} + +void tst_QScriptValue::isString() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isString(); + } +} + +void tst_QScriptValue::isUndefined_data() +{ + values_data(); +} + +void tst_QScriptValue::isUndefined() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isUndefined(); + } +} + +void tst_QScriptValue::isObject_data() +{ + values_data(); +} + +void tst_QScriptValue::isObject() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isObject(); + } +} + +void tst_QScriptValue::isError_data() +{ + values_data(); +} + +void tst_QScriptValue::isError() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isError(); + } +} + +void tst_QScriptValue::toString_data() +{ + values_data(); +} + +void tst_QScriptValue::toString() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toString(); + } +} + +void tst_QScriptValue::toNumber_data() +{ + values_data(); +} + +void tst_QScriptValue::toNumber() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toNumber(); + } +} + +void tst_QScriptValue::toBool_data() +{ + values_data(); +} + +void tst_QScriptValue::toBool() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toBool(); + } +} + +void tst_QScriptValue::toInteger_data() +{ + values_data(); +} + +void tst_QScriptValue::toInteger() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toInteger(); + } +} + +void tst_QScriptValue::toInt32_data() +{ + values_data(); +} + +void tst_QScriptValue::toInt32() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toInt32(); + } +} + +void tst_QScriptValue::toUInt32_data() +{ + values_data(); +} + +void tst_QScriptValue::toUInt32() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toUInt32(); + } +} + +void tst_QScriptValue::toUInt16_data() +{ + values_data(); +} + +void tst_QScriptValue::toUInt16() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toUInt16(); + } +} + +void tst_QScriptValue::toObject_data() +{ + values_data(); +} + +void tst_QScriptValue::toObject() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toObject(); + } +} + +void tst_QScriptValue::equals_data() +{ + values_data(); +} + +void tst_QScriptValue::equals() +{ + QFETCH(QScriptValue, value); + static QScriptValue previous; + QBENCHMARK { + value.equals(previous); + } + previous = value; +} + +void tst_QScriptValue::strictlyEquals_data() +{ + values_data(); +} + +void tst_QScriptValue::strictlyEquals() +{ + QFETCH(QScriptValue, value); + static QScriptValue previous; + QBENCHMARK { + value.strictlyEquals(previous); + } + previous = value; +} + +void tst_QScriptValue::instanceOf_data() +{ + values_data(); +} + +void tst_QScriptValue::instanceOf() +{ + QFETCH(QScriptValue, value); + static QScriptValue object = m_engine->newObject(); + QBENCHMARK { + value.instanceOf(object); + } +} + +QTEST_MAIN(tst_QScriptValue) +#include "tst_qscriptvalue.moc" diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp index d545f37..753fcd0 100644 --- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp +++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp @@ -47,6 +47,8 @@ private slots: void checkSyntax(); void toObject(); void toObjectTwoEngines(); + void newArray(); + void uncaughtException(); }; /* Evaluating a script that throw an unhandled exception should return an invalid value. */ @@ -409,5 +411,107 @@ void tst_QScriptEngine::toObjectTwoEngines() } } +void tst_QScriptEngine::newArray() +{ + QScriptEngine eng; + QScriptValue array = eng.newArray(); + QCOMPARE(array.isValid(), true); + // QCOMPARE(array.isArray(), true); + QCOMPARE(array.isObject(), true); + QVERIFY(!array.isFunction()); + // QCOMPARE(array.scriptClass(), (QScriptClass*)0); + + // Prototype should be Array.prototype. + QCOMPARE(array.prototype().isValid(), true); + // QCOMPARE(array.prototype().isArray(), true); + QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true); + + QScriptValue arrayWithSize = eng.newArray(42); + QCOMPARE(arrayWithSize.isValid(), true); + // QCOMPARE(arrayWithSize.isArray(), true); + QCOMPARE(arrayWithSize.isObject(), true); + QCOMPARE(arrayWithSize.property("length").toInt32(), 42); +} + +void tst_QScriptEngine::uncaughtException() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function foo () { return null; });"); + QVERIFY(!eng.uncaughtException().isValid()); + QVERIFY(fun.isFunction()); + QScriptValue throwFun = eng.evaluate("( function() { throw new Error('Pong'); });"); + QVERIFY(throwFun.isFunction()); + { + eng.evaluate("a = 10"); + QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!eng.uncaughtException().isValid()); + } + { + eng.evaluate("1 = 2"); + QVERIFY(eng.hasUncaughtException()); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + } + { + // Check if the call or toString functions can remove the last exception. + QVERIFY(throwFun.call().isError()); + QVERIFY(eng.hasUncaughtException()); + QScriptValue exception = eng.uncaughtException(); + fun.call(); + exception.toString(); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(exception)); + } + eng.clearExceptions(); + { + // Check if in the call function a new exception can override an existing one. + throwFun.call(); + QVERIFY(eng.hasUncaughtException()); + QScriptValue exception = eng.uncaughtException(); + throwFun.call(); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(!exception.strictlyEquals(eng.uncaughtException())); + } + { + eng.evaluate("throwFun = (function foo () { throw new Error('bla') });"); + eng.evaluate("1;\nthrowFun();"); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), 1); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + } + for (int x = 1; x < 4; ++x) { + QScriptValue ret = eng.evaluate("a = 10;\nb = 20;\n0 = 0;\n", + QString::fromLatin1("FooScript") + QString::number(x), + /* lineNumber */ x); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QString backtrace = QString::fromLatin1("<anonymous>()@FooScript") + QString::number(x) + ":" + QString::number(x + 2); + QCOMPARE(eng.uncaughtExceptionBacktrace().join(""), backtrace); + QVERIFY(fun.call().isNull()); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), -1); + QVERIFY(!eng.uncaughtException().isValid()); + eng.evaluate("2 = 3"); + QVERIFY(eng.hasUncaughtException()); + QScriptValue ret2 = throwFun.call(); + QVERIFY(ret2.isError()); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret2)); + QCOMPARE(eng.uncaughtExceptionLineNumber(), 1); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + eng.evaluate("1 + 2"); + QVERIFY(!eng.hasUncaughtException()); + } +} + QTEST_MAIN(tst_QScriptEngine) #include "tst_qscriptengine.moc" diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp index 27d6df2..2a2a6b1 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp @@ -580,4 +580,17 @@ void tst_QScriptValue::toObjectSimple() } } +void tst_QScriptValue::propertySimple() +{ + QScriptEngine eng; + + QScriptValue simpleObject(eng.evaluate("new Object({ test: 1, other: 2 })")); + QCOMPARE(simpleObject.property("test").toUInt32(), quint32(1)); + QCOMPARE(simpleObject.property("other").toUInt32(), quint32(2)); + + QScriptValue simpleArray(eng.evaluate("new Array(7, 8, 9)")); + QCOMPARE(simpleArray.property("length").toUInt32(), quint32(3)); + QCOMPARE(simpleArray.property(2).toUInt32(), quint32(9)); +} + QTEST_MAIN(tst_QScriptValue) diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h index f9fcedb..af600a6 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h @@ -51,6 +51,7 @@ private slots: void call(); void ctor(); void toObjectSimple(); + void propertySimple(); // Generated test functions. void isBool_data(); diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h index 169c6f6..6bb180c 100644 --- a/JavaScriptCore/runtime/Arguments.h +++ b/JavaScriptCore/runtime/Arguments.h @@ -55,6 +55,10 @@ namespace JSC { class Arguments : public JSObject { public: + // Use an enum because otherwise gcc insists on doing a memory + // read. + enum { MaxArguments = 0x10000 }; + enum NoParametersType { NoParameters }; Arguments(CallFrame*); diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp index 03389c4..38f3ce5 100644 --- a/JavaScriptCore/runtime/Collector.cpp +++ b/JavaScriptCore/runtime/Collector.cpp @@ -245,7 +245,7 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock() Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get(); for (size_t i = 0; i < HeapConstants::cellsPerBlock; ++i) - new (block->cells + i) JSCell(dummyMarkableCellStructure); + new (&block->cells[i]) JSCell(dummyMarkableCellStructure); // Add block to blocks vector. @@ -384,7 +384,7 @@ allocate: do { ASSERT(m_heap.nextCell < HeapConstants::cellsPerBlock); if (!block->marked.get(m_heap.nextCell)) { // Always false for the last cell in the block - Cell* cell = block->cells + m_heap.nextCell; + Cell* cell = &block->cells[m_heap.nextCell]; m_heap.operationInProgress = Allocation; JSCell* imp = reinterpret_cast<JSCell*>(cell); diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h index 34e238c..f5bf113 100644 --- a/JavaScriptCore/runtime/Collector.h +++ b/JavaScriptCore/runtime/Collector.h @@ -24,6 +24,7 @@ #include <stddef.h> #include <string.h> +#include <wtf/FixedArray.h> #include <wtf/HashCountedSet.h> #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> @@ -215,11 +216,11 @@ namespace JSC { const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t); struct CollectorBitmap { - uint32_t bits[BITMAP_WORDS]; + FixedArray<uint32_t, BITMAP_WORDS> bits; bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); } void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); } void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); } - void clearAll() { memset(bits, 0, sizeof(bits)); } + void clearAll() { memset(bits.data(), 0, sizeof(bits)); } ALWAYS_INLINE void advanceToNextPossibleFreeCell(size_t& startCell) { if (!~bits[startCell >> 5]) @@ -248,12 +249,12 @@ namespace JSC { }; struct CollectorCell { - double memory[CELL_ARRAY_LENGTH]; + FixedArray<double, CELL_ARRAY_LENGTH> memory; }; class CollectorBlock { public: - CollectorCell cells[CELLS_PER_BLOCK]; + FixedArray<CollectorCell, CELLS_PER_BLOCK> cells; CollectorBitmap marked; Heap* heap; }; diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h index be6f3c9..9a3327c 100644 --- a/JavaScriptCore/runtime/CollectorHeapIterator.h +++ b/JavaScriptCore/runtime/CollectorHeapIterator.h @@ -77,7 +77,7 @@ namespace JSC { inline JSCell* CollectorHeapIterator::operator*() const { - return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell); + return reinterpret_cast<JSCell*>(&m_heap.blocks[m_block]->cells[m_cell]); } // Iterators advance up to the next-to-last -- and not the last -- cell in a diff --git a/JavaScriptCore/runtime/DateInstanceCache.h b/JavaScriptCore/runtime/DateInstanceCache.h index d208580..b60c29a 100644 --- a/JavaScriptCore/runtime/DateInstanceCache.h +++ b/JavaScriptCore/runtime/DateInstanceCache.h @@ -86,7 +86,7 @@ namespace JSC { CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } - CacheEntry m_cache[cacheSize]; + FixedArray<CacheEntry, cacheSize> m_cache; }; } // namespace JSC diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp index 05623f5..78667cd 100644 --- a/JavaScriptCore/runtime/JSArray.cpp +++ b/JavaScriptCore/runtime/JSArray.cpp @@ -948,10 +948,10 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) { - ASSERT(m_storage->m_length == maxSize); + ASSERT(m_storage->m_length >= maxSize); UNUSED_PARAM(maxSize); JSValue* vector = m_storage->m_vector; - unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); + unsigned vectorEnd = min(maxSize, m_vectorLength); unsigned i = 0; for (; i < vectorEnd; ++i) { JSValue& v = vector[i]; @@ -960,7 +960,7 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz buffer[i] = v; } - for (; i < m_storage->m_length; ++i) + for (; i < maxSize; ++i) buffer[i] = get(exec, i); } diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index 04cb7cf..f625323 100644 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -36,14 +36,13 @@ #include "Nodes.h" #include "Parser.h" #include "StringBuilder.h" -#include "StringExtras.h" #include "dtoa.h" #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> #include <wtf/MathExtras.h> +#include <wtf/StringExtras.h> #include <wtf/unicode/UTF8.h> using namespace WTF; @@ -66,7 +65,7 @@ static JSValue encode(ExecState* exec, const char* doNotEscape) builder.append(c); else { char tmp[4]; - snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c)); + snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c)); builder.append(tmp); } } @@ -386,13 +385,13 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) int u = c[0]; if (u > 255) { char tmp[7]; - sprintf(tmp, "%%u%04X", u); + snprintf(tmp, sizeof(tmp), "%%u%04X", u); builder.append(tmp); } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u))) builder.append(c, 1); else { char tmp[4]; - sprintf(tmp, "%%%02X", u); + snprintf(tmp, sizeof(tmp), "%%%02X", u); builder.append(tmp); } } diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h index f33d9fe..9127b6a 100644 --- a/JavaScriptCore/runtime/JSImmediate.h +++ b/JavaScriptCore/runtime/JSImmediate.h @@ -44,8 +44,6 @@ namespace JSC { class JSObject; class UString; - extern const size_t CELL_MASK; - #if USE(JSVALUE64) inline intptr_t reinterpretDoubleToIntptr(double value) { @@ -597,13 +595,7 @@ namespace JSC { inline bool JSValue::isCell() const { -#ifndef NDEBUG - bool r = !JSImmediate::isImmediate(asValue()); - ASSERT(!r || !(JSImmediate::rawValue(asValue()) & CELL_MASK)); - return r; -#else return !JSImmediate::isImmediate(asValue()); -#endif } inline bool JSValue::isInt32() const diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp index 1d5e639..13c5a51 100644 --- a/JavaScriptCore/runtime/JSString.cpp +++ b/JavaScriptCore/runtime/JSString.cpp @@ -120,7 +120,7 @@ JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UStri size_t fiberCount = 0; UStringImpl* matchString = 0; int matchPosition = -1; - for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { + for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { ++fiberCount; if (matchString) continue; @@ -139,7 +139,7 @@ JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UStri if (UNLIKELY(builder.isOutOfMemory())) return throwOutOfMemoryError(exec); - for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { + for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { UStringImpl* string = *it; if (string != matchString) { builder.append(UString(string)); diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h index 975ef45..53c144b 100644 --- a/JavaScriptCore/runtime/JSString.h +++ b/JavaScriptCore/runtime/JSString.h @@ -417,7 +417,7 @@ namespace JSC { struct JSStringFinalizerStruct { JSStringFinalizerStruct() : m_finalizerCallback(0) {} union { - mutable RopeImpl::Fiber m_fibers[s_maxInternalRopeLength]; + mutable FixedArray<RopeImpl::Fiber, s_maxInternalRopeLength> m_fibers; struct { JSStringFinalizerCallback m_finalizerCallback; void* m_finalizerContext; diff --git a/JavaScriptCore/runtime/NumericStrings.h b/JavaScriptCore/runtime/NumericStrings.h index 89235af..47fbbb2 100644 --- a/JavaScriptCore/runtime/NumericStrings.h +++ b/JavaScriptCore/runtime/NumericStrings.h @@ -27,6 +27,7 @@ #define NumericStrings_h #include "UString.h" +#include <wtf/FixedArray.h> #include <wtf/HashFunctions.h> namespace JSC { @@ -86,10 +87,10 @@ namespace JSC { return smallIntCache[i]; } - CacheEntry<double> doubleCache[cacheSize]; - CacheEntry<int> intCache[cacheSize]; - CacheEntry<unsigned> unsignedCache[cacheSize]; - UString smallIntCache[cacheSize]; + FixedArray<CacheEntry<double>, cacheSize> doubleCache; + FixedArray<CacheEntry<int>, cacheSize> intCache; + FixedArray<CacheEntry<unsigned>, cacheSize> unsignedCache; + FixedArray<UString, cacheSize> smallIntCache; }; } // namespace JSC diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp index 0780984..d8b217d 100644 --- a/JavaScriptCore/runtime/RegExp.cpp +++ b/JavaScriptCore/runtime/RegExp.cpp @@ -46,30 +46,23 @@ namespace JSC { -inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern) - : m_pattern(pattern) - , m_flagBits(0) - , m_constructionError(0) - , m_numSubpatterns(0) -{ - compile(globalData); -} - inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags) : m_pattern(pattern) , m_flagBits(0) , m_constructionError(0) , m_numSubpatterns(0) + , m_lastMatchStart(-1) { // NOTE: The global flag is handled on a case-by-case basis by functions like // String::match and RegExpObject::match. - if (flags.find('g') != UString::NotFound) - m_flagBits |= Global; - if (flags.find('i') != UString::NotFound) - m_flagBits |= IgnoreCase; - if (flags.find('m') != UString::NotFound) - m_flagBits |= Multiline; - + if (!flags.isNull()) { + if (flags.find('g') != UString::NotFound) + m_flagBits |= Global; + if (flags.find('i') != UString::NotFound) + m_flagBits |= IgnoreCase; + if (flags.find('m') != UString::NotFound) + m_flagBits |= Multiline; + } compile(globalData); } @@ -80,11 +73,6 @@ RegExp::~RegExp() } #endif -PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern) -{ - return adoptRef(new RegExp(globalData, pattern)); -} - PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags) { return adoptRef(new RegExp(globalData, pattern, flags)); @@ -109,8 +97,24 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) if (ovector) ovector->resize(0); - if (static_cast<unsigned>(startOffset) > s.size() || s.isNull()) + if (static_cast<unsigned>(startOffset) > s.size() || s.isNull()) { + m_lastMatchString = UString(); + m_lastMatchStart = -1; + m_lastOVector.shrink(0); return -1; + } + + // Perform check to see if this match call is the same as the last match invocation + // and if it is return the prior result. + if ((startOffset == m_lastMatchStart) && (s.rep() == m_lastMatchString.rep())) { + if (ovector) + *ovector = m_lastOVector; + + if (m_lastOVector.isEmpty()) + return -1; + + return m_lastOVector.at(0); + } #if ENABLE(YARR_JIT) if (!!m_regExpJITCode) { @@ -147,9 +151,22 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) if (ovector) ovector->clear(); } + + m_lastMatchString = s; + m_lastMatchStart = startOffset; + + if (ovector) + m_lastOVector = *ovector; + else + m_lastOVector = nonReturnedOvector; + return result; } + m_lastMatchString = UString(); + m_lastMatchStart = -1; + m_lastOVector.shrink(0); + return -1; } diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h index 695b688..8ea44e3 100644 --- a/JavaScriptCore/runtime/RegExp.h +++ b/JavaScriptCore/runtime/RegExp.h @@ -37,7 +37,6 @@ namespace JSC { class RegExp : public RefCounted<RegExp> { public: - static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern); static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags); #if !ENABLE(YARR) ~RegExp(); @@ -56,7 +55,6 @@ namespace JSC { unsigned numSubpatterns() const { return m_numSubpatterns; } private: - RegExp(JSGlobalData* globalData, const UString& pattern); RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags); void compile(JSGlobalData*); @@ -67,6 +65,9 @@ namespace JSC { int m_flagBits; const char* m_constructionError; unsigned m_numSubpatterns; + UString m_lastMatchString; + int m_lastMatchStart; + Vector<int, 32> m_lastOVector; #if ENABLE(YARR_JIT) Yarr::RegexCodeBlock m_regExpJITCode; diff --git a/JavaScriptCore/runtime/RegExpCache.cpp b/JavaScriptCore/runtime/RegExpCache.cpp index 192df4d..b9d250d 100644 --- a/JavaScriptCore/runtime/RegExpCache.cpp +++ b/JavaScriptCore/runtime/RegExpCache.cpp @@ -34,25 +34,26 @@ namespace JSC { PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags) { if (patternString.size() < maxCacheablePatternLength) { - pair<HashMap<RegExpKey, RefPtr<RegExp> >::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0); + pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0); if (!result.second) return result.first->second; + else + return create(patternString, flags, result.first); } - return create(patternString, flags); + return create(patternString, flags, m_cacheMap.end()); } -PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags) +PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator) { - RefPtr<RegExp> regExp; - - if (!flags.isNull()) - regExp = RegExp::create(m_globalData, patternString, flags); - else - regExp = RegExp::create(m_globalData, patternString); + RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags); if (patternString.size() >= maxCacheablePatternLength) return regExp; + RegExpKey key = RegExpKey(flags, patternString); + iterator->first = key; + iterator->second = regExp; + ++m_nextKeyToEvict; if (m_nextKeyToEvict == maxCacheableEntries) { m_nextKeyToEvict = 0; @@ -61,8 +62,6 @@ PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UStri if (m_isFull) m_cacheMap.remove(RegExpKey(patternKeyArray[m_nextKeyToEvict].flagsValue, patternKeyArray[m_nextKeyToEvict].pattern)); - RegExpKey key = RegExpKey(flags, patternString); - m_cacheMap.set(key, regExp); patternKeyArray[m_nextKeyToEvict].flagsValue = key.flagsValue; patternKeyArray[m_nextKeyToEvict].pattern = patternString.rep(); return regExp; diff --git a/JavaScriptCore/runtime/RegExpCache.h b/JavaScriptCore/runtime/RegExpCache.h index 03b73ac..fb30a9e 100644 --- a/JavaScriptCore/runtime/RegExpCache.h +++ b/JavaScriptCore/runtime/RegExpCache.h @@ -35,17 +35,19 @@ namespace JSC { class RegExpCache { + +typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap; + public: PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags); - PassRefPtr<RegExp> create(const UString& patternString, const UString& flags); + PassRefPtr<RegExp> create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator); RegExpCache(JSGlobalData* globalData); private: static const unsigned maxCacheablePatternLength = 256; static const int maxCacheableEntries = 256; - typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap; - RegExpKey patternKeyArray[maxCacheableEntries]; + FixedArray<RegExpKey, maxCacheableEntries> patternKeyArray; RegExpCacheMap m_cacheMap; JSGlobalData* m_globalData; int m_nextKeyToEvict; diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h index bc337c9..b550a04 100644 --- a/JavaScriptCore/runtime/SmallStrings.h +++ b/JavaScriptCore/runtime/SmallStrings.h @@ -27,6 +27,7 @@ #define SmallStrings_h #include "UString.h" +#include <wtf/FixedArray.h> #include <wtf/OwnPtr.h> namespace JSC { @@ -61,14 +62,14 @@ namespace JSC { unsigned count() const; #if ENABLE(JIT) - JSString** singleCharacterStrings() { return m_singleCharacterStrings; } + JSString** singleCharacterStrings() { return m_singleCharacterStrings.data(); } #endif private: void createEmptyString(JSGlobalData*); void createSingleCharacterString(JSGlobalData*, unsigned char); JSString* m_emptyString; - JSString* m_singleCharacterStrings[0x100]; + FixedArray<JSString*, 0x100> m_singleCharacterStrings; OwnPtr<SmallStringsStorage> m_storage; }; diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp index 1c11936..5a6a644 100644 --- a/JavaScriptCore/runtime/UString.cpp +++ b/JavaScriptCore/runtime/UString.cpp @@ -32,17 +32,14 @@ #include <ctype.h> #include <limits.h> #include <limits> -#include <math.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> #include <wtf/MathExtras.h> #include <wtf/StringExtras.h> #include <wtf/Vector.h> #include <wtf/unicode/UTF8.h> -#include <wtf/StringExtras.h> #if HAVE(STRINGS_H) #include <strings.h> @@ -96,7 +93,7 @@ UString UString::from(int i) *--p = '0'; else if (i == INT_MIN) { char minBuf[1 + sizeof(i) * 3]; - sprintf(minBuf, "%d", INT_MIN); + snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN); return UString(minBuf); } else { bool negative = false; @@ -126,9 +123,9 @@ UString UString::from(long long i) else if (i == std::numeric_limits<long long>::min()) { char minBuf[1 + sizeof(i) * 3]; #if OS(WINDOWS) - snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min()); + snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min()); #else - snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min()); + snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min()); #endif return UString(minBuf); } else { @@ -176,7 +173,7 @@ UString UString::from(long l) *--p = '0'; else if (l == LONG_MIN) { char minBuf[1 + sizeof(l) * 3]; - sprintf(minBuf, "%ld", LONG_MIN); + snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN); return UString(minBuf); } else { bool negative = false; diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h index 4364021..bae9265 100644 --- a/JavaScriptCore/runtime/UString.h +++ b/JavaScriptCore/runtime/UString.h @@ -158,21 +158,43 @@ namespace JSC { ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) { - unsigned size = s1.size(); - switch (size) { - case 0: - return !s2.size(); + UString::Rep* rep1 = s1.rep(); + UString::Rep* rep2 = s2.rep(); + unsigned size1 = 0; + unsigned size2 = 0; + + if (rep1 == rep2) // If they're the same rep, they're equal. + return true; + + if (rep1) + size1 = rep1->length(); + + if (rep2) + size2 = rep2->length(); + + if (size1 != size2) // If the lengths are not the same, we're done. + return false; + + if (!size1) + return true; + + // At this point we know + // (a) that the strings are the same length and + // (b) that they are greater than zero length. + const UChar* d1 = rep1->characters(); + const UChar* d2 = rep2->characters(); + + if (d1 == d2) // Check to see if the data pointers are the same. + return true; + + // Do quick checks for sizes 1 and 2. + switch (size1) { case 1: - return s2.size() == 1 && s1.data()[0] == s2.data()[0]; - case 2: { - if (s2.size() != 2) - return false; - const UChar* d1 = s1.data(); - const UChar* d2 = s2.data(); + return d1[0] == d2[0]; + case 2: return (d1[0] == d2[0]) & (d1[1] == d2[1]); - } default: - return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0; + return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; } } diff --git a/JavaScriptCore/wtf/AVLTree.h b/JavaScriptCore/wtf/AVLTree.h index d7470e7..ec8a639 100644 --- a/JavaScriptCore/wtf/AVLTree.h +++ b/JavaScriptCore/wtf/AVLTree.h @@ -33,6 +33,7 @@ #define AVL_TREE_H_ #include "Assertions.h" +#include <wtf/FixedArray.h> namespace WTF { @@ -70,7 +71,7 @@ public: void reset() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = false; } private: - bool m_data[maxDepth]; + FixedArray<bool, maxDepth> m_data; }; // How to determine maxDepth: diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h index d26b939..afeae0c 100644 --- a/JavaScriptCore/wtf/Assertions.h +++ b/JavaScriptCore/wtf/Assertions.h @@ -55,6 +55,10 @@ #include <e32debug.h> #endif +#if PLATFORM(BREWMP) +#include <AEEStdLib.h> +#endif + #ifdef NDEBUG /* Disable ASSERT* macros in release mode. */ #define ASSERTIONS_DISABLED_DEFAULT 1 @@ -163,6 +167,12 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann __DEBUGGER(); \ User::Panic(_L("Webkit CRASH"),0); \ } while(false) +#elif PLATFORM(BREWMP) +#define CRASH() do { \ + DBGPRINTF_FATAL("WebKit CRASH"); \ + *(int *)(uintptr_t)0xbbadbeef = 0; \ + ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ +} while(false) #else #define CRASH() do { \ *(int *)(uintptr_t)0xbbadbeef = 0; \ diff --git a/JavaScriptCore/wtf/FixedArray.h b/JavaScriptCore/wtf/FixedArray.h new file mode 100644 index 0000000..66f2327 --- /dev/null +++ b/JavaScriptCore/wtf/FixedArray.h @@ -0,0 +1,53 @@ +/* + * 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 FixedArray_h +#define FixedArray_h + +#include <wtf/Assertions.h> + +namespace WTF { +template <typename T, int Size> class FixedArray { +public: + T& operator[](size_t i) + { + ASSERT(i < Size); + return m_data[i]; + } + + const T& operator[](size_t i) const + { + ASSERT(i < Size); + return m_data[i]; + } + + T* data() { return m_data; } +private: + T m_data[Size]; +}; +} +using WTF::FixedArray; + +#endif // FixedArray_h diff --git a/JavaScriptCore/wtf/HashSet.h b/JavaScriptCore/wtf/HashSet.h index 4429490..66639e4 100644 --- a/JavaScriptCore/wtf/HashSet.h +++ b/JavaScriptCore/wtf/HashSet.h @@ -48,7 +48,7 @@ namespace WTF { HashFunctions, ValueTraits, ValueTraits> HashTableType; public: - typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; + typedef HashTableConstIteratorAdapter<HashTableType, ValueType> iterator; typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator; void swap(HashSet&); @@ -57,13 +57,10 @@ namespace WTF { int capacity() const; bool isEmpty() const; - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; + iterator begin() const; + iterator end() const; - iterator find(const ValueType&); - const_iterator find(const ValueType&) const; + iterator find(const ValueType&) const; bool contains(const ValueType&) const; // An alternate version of find() that finds the object by hashing and comparing @@ -71,8 +68,7 @@ namespace WTF { // must have the following function members: // static unsigned hash(const T&); // static bool equal(const ValueType&, const T&); - template<typename T, typename HashTranslator> iterator find(const T&); - template<typename T, typename HashTranslator> const_iterator find(const T&) const; + template<typename T, typename HashTranslator> iterator find(const T&) const; template<typename T, typename HashTranslator> bool contains(const T&) const; // The return value is a pair of an interator to the new value's location, @@ -137,37 +133,19 @@ namespace WTF { } template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::begin() + inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::begin() const { return m_impl.begin(); } template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::end() + inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::end() const { return m_impl.end(); } template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::begin() const - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::end() const - { - return m_impl.end(); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::find(const ValueType& value) - { - return m_impl.find(value); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::find(const ValueType& value) const + inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::find(const ValueType& value) const { return m_impl.find(value); } @@ -181,15 +159,6 @@ namespace WTF { template<typename Value, typename HashFunctions, typename Traits> template<typename T, typename HashTranslator> typename HashSet<Value, HashFunctions, Traits>::iterator - inline HashSet<Value, HashFunctions, Traits>::find(const T& value) - { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; - return m_impl.template find<T, Adapter>(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename HashTranslator> - typename HashSet<Value, HashFunctions, Traits>::const_iterator inline HashSet<Value, HashFunctions, Traits>::find(const T& value) const { typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h index ceb8963..1c4ae6d 100644 --- a/JavaScriptCore/wtf/HashTable.h +++ b/JavaScriptCore/wtf/HashTable.h @@ -333,6 +333,7 @@ namespace WTF { void remove(const KeyType&); void remove(iterator); void removeWithoutEntryConsistencyCheck(iterator); + void removeWithoutEntryConsistencyCheck(const_iterator); void clear(); static bool isEmptyBucket(const ValueType& value) { return Extractor::extract(value) == KeyTraits::emptyValue(); } @@ -854,6 +855,15 @@ namespace WTF { } template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> + inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeWithoutEntryConsistencyCheck(const_iterator it) + { + if (it == end()) + return; + + removeAndInvalidateWithoutEntryConsistencyCheck(const_cast<ValueType*>(it.m_position)); + } + + template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(const KeyType& key) { remove(find(key)); diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h index d7a9341..7c5d868 100644 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ b/JavaScriptCore/wtf/PassRefPtr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 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 @@ -27,69 +27,61 @@ namespace WTF { template<typename T> class RefPtr; template<typename T> class PassRefPtr; - template <typename T> PassRefPtr<T> adoptRef(T*); + template<typename T> PassRefPtr<T> adoptRef(T*); + inline void adopted(const void*) { } - // Remove inline for WINSCW compiler to prevent the compiler agressively resolving - // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as - // a class member or function arguments before T is defined. - - // [Qt]r57240 broke Qt build (might be a gcc bug) - // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253 - template<typename T> #if !COMPILER(WINSCW) #if !PLATFORM(QT) - ALWAYS_INLINE + #define REF_DEREF_INLINE ALWAYS_INLINE #else - inline + // Using ALWAYS_INLINE broke the Qt build. This may be a GCC bug. + // See https://bugs.webkit.org/show_bug.cgi?id=37253 for details. + #define REF_DEREF_INLINE inline #endif +#else + // No inlining for WINSCW compiler to prevent the compiler agressively resolving + // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as + // a class member or function arguments before T is defined. + #define REF_DEREF_INLINE #endif - void refIfNotNull(T* ptr) + + template<typename T> REF_DEREF_INLINE void refIfNotNull(T* ptr) { if (UNLIKELY(ptr != 0)) ptr->ref(); } - // [Qt]r57240 broke Qt build (might be a gcc bug) - // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253 - template<typename T> -#if !COMPILER(WINSCW) -#if !PLATFORM(QT) - ALWAYS_INLINE -#else - inline -#endif -#endif - void derefIfNotNull(T* ptr) + template<typename T> REF_DEREF_INLINE void derefIfNotNull(T* ptr) { if (UNLIKELY(ptr != 0)) ptr->deref(); } + #undef REF_DEREF_INLINE + template<typename T> class PassRefPtr { public: - PassRefPtr() : m_ptr(0) {} + PassRefPtr() : m_ptr(0) { } PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } // It somewhat breaks the type system to allow transfer of ownership out of // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr - // temporaries, and we don't really have a need to use real const PassRefPtrs - // anyway. - PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {} - template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } + // temporaries, and we don't have a need to use real const PassRefPtrs anyway. + PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) { } + template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } - template <class U> - PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); } + template<typename U> PassRefPtr(const RefPtr<U>&); T* get() const { return m_ptr; } void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; } - T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; } + T* leakRef() const; T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } - + bool operator!() const { return !m_ptr; } // This conversion operator allows implicit conversion to bool but not to other integer types. @@ -98,13 +90,18 @@ namespace WTF { PassRefPtr& operator=(T*); PassRefPtr& operator=(const PassRefPtr&); - template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&); - template <typename U> PassRefPtr& operator=(const RefPtr<U>&); + template<typename U> PassRefPtr& operator=(const PassRefPtr<U>&); + template<typename U> PassRefPtr& operator=(const RefPtr<U>&); friend PassRefPtr adoptRef<T>(T*); + + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + T* releaseRef() const { return leakRef(); } + private: // adopting constructor - PassRefPtr(T* ptr, bool) : m_ptr(ptr) {} + PassRefPtr(T* ptr, bool) : m_ptr(ptr) { } + mutable T* m_ptr; }; @@ -116,7 +113,7 @@ namespace WTF { // if we use inheritance, GCC's optimizer fails to realize that destruction // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the // most important code from PassRefPtr. - template <typename T> class NonNullPassRefPtr { + template<typename T> class NonNullPassRefPtr { public: NonNullPassRefPtr(T* ptr) : m_ptr(ptr) @@ -125,7 +122,7 @@ namespace WTF { m_ptr->ref(); } - template <class U> NonNullPassRefPtr(const RefPtr<U>& o) + template<typename U> NonNullPassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { ASSERT(m_ptr); @@ -138,13 +135,13 @@ namespace WTF { ASSERT(m_ptr); } - template <class U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) + template<typename U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) : m_ptr(o.releaseRef()) { ASSERT(m_ptr); } - template <class U> NonNullPassRefPtr(const PassRefPtr<U>& o) + template<typename U> NonNullPassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { ASSERT(m_ptr); @@ -164,7 +161,21 @@ namespace WTF { mutable T* m_ptr; }; - template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) + template<typename T> template<typename U> inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o) + : m_ptr(o.get()) + { + T* ptr = m_ptr; + refIfNotNull(ptr); + } + + template<typename T> inline T* PassRefPtr<T>::leakRef() const + { + T* ptr = m_ptr; + m_ptr = 0; + return ptr; + } + + template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); refIfNotNull(optr); @@ -174,7 +185,7 @@ namespace WTF { return *this; } - template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) + template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) { refIfNotNull(optr); T* ptr = m_ptr; @@ -183,7 +194,7 @@ namespace WTF { return *this; } - template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) + template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) { T* ptr = m_ptr; m_ptr = ref.releaseRef(); @@ -191,7 +202,7 @@ namespace WTF { return *this; } - template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) + template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) { T* ptr = m_ptr; m_ptr = ref.releaseRef(); @@ -199,72 +210,73 @@ namespace WTF { return *this; } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b) { return a.get() == b; } - template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b) { return a == b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b) { return a.get() != b; } - template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b) { return a != b.get(); } - template <typename T> inline PassRefPtr<T> adoptRef(T* p) + template<typename T> inline PassRefPtr<T> adoptRef(T* p) { + adopted(p); return PassRefPtr<T>(p, true); } - template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) + template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) { return adoptRef(static_cast<T*>(p.releaseRef())); } - template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) + template<typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) { return adoptRef(const_cast<T*>(p.releaseRef())); } - template <typename T> inline T* getPtr(const PassRefPtr<T>& p) + template<typename T> inline T* getPtr(const PassRefPtr<T>& p) { return p.get(); } diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index b92d267..feb3a4d 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -615,6 +615,10 @@ #define WTF_USE_CARBON_SECURE_INPUT_MODE 1 #endif +#if PLATFORM(BREWMP) +#define ENABLE_SINGLE_THREADED 1 +#endif + #if PLATFORM(QT) && OS(DARWIN) #define WTF_PLATFORM_CF 1 #endif @@ -719,6 +723,7 @@ #if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD) #define HAVE_DISPATCH_H 1 +#define HAVE_HOSTED_CORE_ANIMATION 1 #if !PLATFORM(IPHONE) #define HAVE_MADV_FREE_REUSE 1 @@ -986,7 +991,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #endif #endif #if (CPU(X86) && USE(JSVALUE32_64)) || (CPU(X86_64) && USE(JSVALUE64)) \ - || CPU(ARM) + || CPU(ARM) \ + || CPU(MIPS) #if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 #endif @@ -1105,10 +1111,6 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_JSC_ZOMBIES 0 -#if !defined(BUILDING_ON_TIGER) -#define ENABLE_RECURSIVE_PARSE 1 -#endif - /* FIXME: Eventually we should enable this for all platforms and get rid of the define. */ #if PLATFORM(MAC) #define WTF_USE_PLATFORM_STRATEGIES 1 diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h index 761a856..5aedac3 100644 --- a/JavaScriptCore/wtf/RefCounted.h +++ b/JavaScriptCore/wtf/RefCounted.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 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 @@ -24,6 +24,9 @@ #include <wtf/Assertions.h> #include <wtf/Noncopyable.h> +// Remove this once we make all WebKit code compatible with stricter rules about RefCounted. +#define LOOSE_REF_COUNTED + namespace WTF { // This base class holds the non-template methods and attributes. @@ -34,6 +37,9 @@ public: void ref() { ASSERT(!m_deletionHasBegun); +#ifndef LOOSE_REF_COUNTED + ASSERT(!m_adoptionIsRequired); +#endif ++m_refCount; } @@ -53,18 +59,27 @@ protected: : m_refCount(1) #ifndef NDEBUG , m_deletionHasBegun(false) + , m_adoptionIsRequired(true) #endif { } ~RefCountedBase() { +#ifndef LOOSE_REF_COUNTED + ASSERT(m_deletionHasBegun); + ASSERT(!m_adoptionIsRequired); +#endif } // Returns whether the pointer should be freed or not. bool derefBase() { ASSERT(!m_deletionHasBegun); +#ifndef LOOSE_REF_COUNTED + ASSERT(!m_adoptionIsRequired); +#endif + ASSERT(m_refCount > 0); if (m_refCount == 1) { #ifndef NDEBUG @@ -91,17 +106,32 @@ protected: #endif private: - template<class T> - friend class CrossThreadRefCounted; + template<typename T> friend class CrossThreadRefCounted; + +#ifndef NDEBUG + friend void adopted(RefCountedBase*); +#endif int m_refCount; #ifndef NDEBUG bool m_deletionHasBegun; + bool m_adoptionIsRequired; #endif }; +#ifndef NDEBUG + +inline void adopted(RefCountedBase* object) +{ + if (!object) + return; + ASSERT(!object->m_deletionHasBegun); + object->m_adoptionIsRequired = false; +} + +#endif -template<class T> class RefCounted : public RefCountedBase, public Noncopyable { +template<typename T> class RefCounted : public RefCountedBase, public Noncopyable { public: void deref() { @@ -115,7 +145,7 @@ protected: } }; -template<class T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated { +template<typename T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated { public: void deref() { diff --git a/JavaScriptCore/wtf/StringExtras.h b/JavaScriptCore/wtf/StringExtras.h index 8156580..342261b 100644 --- a/JavaScriptCore/wtf/StringExtras.h +++ b/JavaScriptCore/wtf/StringExtras.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Inc. All rights reserved. + * Copyright (C) 2006, 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 @@ -44,17 +44,30 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...) va_start(args, format); result = _vsnprintf(buffer, count, format, args); va_end(args); + + // In the case where the string entirely filled the buffer, _vsnprintf will not + // null-terminate it, but snprintf must. + if (count > 0) + buffer[count - 1] = '\0'; + return result; } -#if COMPILER(MSVC7_OR_LOWER) || OS(WINCE) - -inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args) +inline double wtf_vsnprintf(char* buffer, size_t count, const char* format, va_list args) { - return _vsnprintf(buffer, count, format, args); + int result = _vsnprintf(buffer, count, format, args); + + // In the case where the string entirely filled the buffer, _vsnprintf will not + // null-terminate it, but vsnprintf must. + if (count > 0) + buffer[count - 1] = '\0'; + + return result; } -#endif +// Work around a bug in Microsoft's implementation of vsnprintf, where +// vsnprintf does not null terminate the buffer +#define vsnprintf(buffer, count, format, args) wtf_vsnprintf(buffer, count, format, args) #if OS(WINCE) diff --git a/JavaScriptCore/wtf/efl/MainThreadEfl.cpp b/JavaScriptCore/wtf/efl/MainThreadEfl.cpp index fe32d1b..8774d20 100644 --- a/JavaScriptCore/wtf/efl/MainThreadEfl.cpp +++ b/JavaScriptCore/wtf/efl/MainThreadEfl.cpp @@ -42,7 +42,7 @@ void initializeMainThreadPlatform() { } -static int timeoutFired(void*) +static Eina_Bool timeoutFired(void*) { dispatchFunctionsFromMainThread(); return ECORE_CALLBACK_CANCEL; diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h index 244009f..a172e2c 100644 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ b/JavaScriptCore/wtf/text/StringImpl.h @@ -257,6 +257,37 @@ public: memcpy(destination, source, numCharacters * sizeof(UChar)); } + PassRefPtr<StringImpl> copyStringWithoutBOMs(bool definitelyHasBOMs, bool& hasBOMs) + { + static const UChar byteOrderMark = 0xFEFF; + size_t i = 0; + if (!definitelyHasBOMs) { + hasBOMs = false; + // ECMA-262 calls for stripping all Cf characters, but we only strip BOM characters. + // See <https://bugs.webkit.org/show_bug.cgi?id=4931> for details. + for (; i < m_length; i++) { + if (UNLIKELY(m_data[i] == byteOrderMark)) { + hasBOMs = true; + break; + } + } + if (!hasBOMs) + return this; + } + Vector<UChar> result; + result.reserveInitialCapacity(m_length); + size_t firstBOM = i; + i = 0; + for (; i < firstBOM; i++) + result.append(m_data[i]); + for (; i < m_length; i++) { + UChar c = m_data[i]; + if (c != byteOrderMark) + result.append(c); + } + return StringImpl::adopt(result); + } + // Returns a StringImpl suitable for use on another thread. PassRefPtr<StringImpl> crossThreadString(); // Makes a deep copy. Helpful only if you need to use a String on another thread diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp index 2df44f8..42f0ff8 100644 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp @@ -77,6 +77,11 @@ bool isPunct(wchar_t c) return !!iswpunct(c); } +bool isAlphanumeric(wchar_t c) +{ + return !!iswalnum(c); +} + int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) { const UChar* sourceIterator = source; diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h index 5bed9e8..68da35a 100644 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h @@ -165,6 +165,7 @@ namespace WTF { 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; } @@ -183,9 +184,9 @@ namespace WTF { unsigned char combiningClass(UChar32); DecompositionType decompositionType(UChar32); Direction direction(UChar32); - inline bool isArabicChar(UChar32) + inline bool isArabicChar(UChar32 c) { - return false; // FIXME: implement! + return c >= 0x0600 && c <= 0x06FF; } inline bool hasLineBreakingPropertyComplexContext(UChar32) diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp index 34ccc00..09c82d1 100644 --- a/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -1554,7 +1554,7 @@ public: } case PatternTerm::TypeParentheticalAssertion: { - unsigned alternativeFrameLocation = term.inputPosition + RegexStackSpaceForBackTrackInfoParentheticalAssertion; + unsigned alternativeFrameLocation = term.frameLocation + RegexStackSpaceForBackTrackInfoParentheticalAssertion; atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation); emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0); |