diff options
author | Kristian Monsen <kristianm@google.com> | 2010-07-30 10:46:49 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-08-04 13:01:34 +0100 |
commit | 0617145a89917ae7735fe1c9538688ab9a577df5 (patch) | |
tree | 56206078694427c37ed7bdf27eb5221398b833c0 /JavaScriptCore | |
parent | ef1adcdfc805d4d13103f6f15cc5b4d96828a60f (diff) | |
download | external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.zip external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.gz external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.bz2 |
Merge WebKit at r64264 : Initial merge by git.
Change-Id: Ic42bef02efef8217a0f84c47176a9c617c28d1f1
Diffstat (limited to 'JavaScriptCore')
57 files changed, 3022 insertions, 1199 deletions
diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk index 42df087..d55d8ab 100644 --- a/JavaScriptCore/Android.mk +++ b/JavaScriptCore/Android.mk @@ -167,6 +167,7 @@ LOCAL_SRC_FILES := \ wtf/HashTable.cpp \ wtf/MD5.cpp \ wtf/MainThread.cpp \ + jit/PageAllocation.cpp\ wtf/RandomNumber.cpp \ wtf/RefCountedLeakCounter.cpp \ wtf/TCSystemAlloc.cpp \ diff --git a/JavaScriptCore/CMakeLists.txt b/JavaScriptCore/CMakeLists.txt index efcc05d..08a0e72 100644 --- a/JavaScriptCore/CMakeLists.txt +++ b/JavaScriptCore/CMakeLists.txt @@ -168,6 +168,7 @@ SET(JavaScriptCore_SOURCES yarr/RegexJIT.cpp wtf/DateMath.cpp + wtf/PageAllocation.cpp ) SET(JavaScriptCore_HEADERS ) diff --git a/JavaScriptCore/CMakeListsEfl.txt b/JavaScriptCore/CMakeListsEfl.txt index 945ad52..7897ea5 100644 --- a/JavaScriptCore/CMakeListsEfl.txt +++ b/JavaScriptCore/CMakeListsEfl.txt @@ -1,6 +1,6 @@ LIST(APPEND JavaScriptCore_SOURCES jit/ExecutableAllocatorFixedVMPool.cpp - jit/ExecutableAllocatorPosix.cpp + jit/ExecutableAllocator.cpp runtime/MarkStackPosix.cpp ) diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 5e01de2..2e8c1d1 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,570 @@ +2010-07-28 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Darin Adler. + + Bug 43162 - Add support for MADV_FREE to PageAllocation. + + * wtf/PageAllocation.cpp: + (WTF::PageAllocation::commit): + (WTF::PageAllocation::decommit): + +2010-07-27 Kinuko Yasuda <kinuko@chromium.org> + + Reviewed by Ojan Vafai. + + Add FILE_SYSTEM build flag for FileSystem API + https://bugs.webkit.org/show_bug.cgi?id=42915 + + * Configurations/FeatureDefines.xcconfig: + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Temporarily rolling out http://trac.webkit.org/changeset/64177, + this seems to give QT ARM/Win a headache (specifically, looks + like structure layour differs, objects get too large - + "..\..\..\JavaScriptCore\runtime\ArrayPrototype.cpp:41:" + "error: size of array 'dummyclass_fits_in_cell' is negative"). + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncShift): + (JSC::arrayProtoFuncSplice): + (JSC::arrayProtoFuncUnShift): + * runtime/JSArray.cpp: + (JSC::increasedVectorLength): + (JSC::JSArray::JSArray): + (JSC::JSArray::~JSArray): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::putSlowCase): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::subclassData): + (JSC::JSArray::setSubclassData): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::length): + (JSC::JSArray::canGetIndex): + (JSC::JSArray::getIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::uncheckedSetIndex): + (JSC::JSArray::markChildrenDirect): + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Speculative build fix for Chromium/Win + + * wtf/Platform.h: + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Oh! that makes more sense! Maybe C++-style comments are bringing teh bad mojo. + + * wtf/Platform.h: + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Speculative build fix for GTK/64 ... seems to be barfing on a comment o_O + + * wtf/Platform.h: + +2010-07-27 Michael Saboff <msaboff@apple.com> + + Reviewed by Gavin Barraclough. + + Changed the handling for removing and adding elements at the front + of an array. The code now keeps a bias that indicates the amount of + JSValue sized holes are prior to the ArrayStorage block. This means + that shift operations are now memmove's of the header part of + the ArrayStorage and unshift operations are similar, but may require a + realloc first to create the space. Similar operations are performed + for special cases of splice and slice. + Also optimized the new Array(size) case so that we don't allocate and + initialize array elements until the JS code starts using elements. + The array growth code is slightly more aggressive for initial growth + based on size growth of any previous array. + + * Configurations/JavaScriptCore.xcconfig: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncShift): + (JSC::arrayProtoFuncSplice): + (JSC::arrayProtoFuncUnShift): + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + (JSC::JSArray::~JSArray): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::putSlowCase): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::getNewVectorLength): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::increaseVectorPrefixLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::shiftCount): + (JSC::JSArray::unshiftCount): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::subclassData): + (JSC::JSArray::setSubclassData): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::length): + (JSC::JSArray::canGetIndex): + (JSC::JSArray::getIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::uncheckedSetIndex): + (JSC::JSArray::arrayStorage): + (JSC::JSArray::setArrayStorage): + (JSC::JSArray::markChildrenDirect): + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 43089 - Cleanup JIT related switched in Platform.h + + The code the enable to JIT checks every permutation of platform & OS individually, but + now the JIT is enabled on the majority much all x86/x86-64/ARM/MIPS systems. It should + be cleaner to just enable by default on these platforms, and explicitly disable on configs + that don't aren't supported. + + Also, rename ENABLE_JIT_OPTIMIZE_MOD to ENABLE_JIT_USE_SOFT_MODULO. I always find this + confusing since enabling this "optimization" would be possible, but would be a regression + on x86/x86-64 systems! I think it's clearer to reserve "JIT_OPTIMIZE" for compiler + technologies applicable to all platforms, and make a more optional behaviour like this a + "USE". + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + * jit/JITArithmetic32_64.cpp: + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * wtf/Platform.h: + +2010-07-27 James Robinson <jamesr@chromium.org> + + Reviewed by Darin Fisher. + + [chromium] Make PLATFORM(CHROMIUM) and not OS(MAC) turn USE(GLES2_RENDERING) on + https://bugs.webkit.org/show_bug.cgi?id=43084 + + This turns USE(GLES2_RENDERING) on for chromium on windows/linux. This causes no + change in behavior, that's all controlled by ENABLE() macros that are currently off. + + * wtf/Platform.h: + +2010-07-23 Helder Correia <heldercorreia@codeaurora.org> + + Reviewed by Darin Adler. + + Canvas tests 2d.imageData.object.round and 2d.imageData.object.wrap are + failing. For canvas image data manipulation, the values passed should + be truncated and wrapped. Also fix the canvas-ImageData-behaviour test + to expect wrapping rather than clamping, and add some new checkings. + https://bugs.webkit.org/show_bug.cgi?id=40272 + + * runtime/JSByteArray.h: + (JSC::JSByteArray::setIndex): + (JSC::JSByteArray::JSByteArray): + +2010-07-27 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 42621 - Add a bump allocator for the YARR interpreter + + The regex engine requires lifo allocation, however currently uses the general purpose + malloc/free memory allocation. A simple bump pointer allocator should provide a lower + overhead allocation solution. + + When using YARR interpreter, 15% progression on v8-regex. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSGlobalData.h: + * runtime/RegExp.cpp: + (JSC::RegExp::compile): + * wtf/BumpPointerAllocator.h: Added. + (WTF::BumpPointerPool::ensureCapacity): + (WTF::BumpPointerPool::alloc): + (WTF::BumpPointerPool::dealloc): + (WTF::BumpPointerPool::operator new): + (WTF::BumpPointerPool::BumpPointerPool): + (WTF::BumpPointerPool::create): + (WTF::BumpPointerPool::shrink): + (WTF::BumpPointerPool::destroy): + (WTF::BumpPointerPool::ensureCapacityCrossPool): + (WTF::BumpPointerPool::deallocCrossPool): + (WTF::BumpPointerAllocator::BumpPointerAllocator): + (WTF::BumpPointerAllocator::~BumpPointerAllocator): + (WTF::BumpPointerAllocator::startAllocator): + (WTF::BumpPointerAllocator::stopAllocator): + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::Interpreter::allocDisjunctionContext): + (JSC::Yarr::Interpreter::freeDisjunctionContext): + (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext): + (JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext): + (JSC::Yarr::Interpreter::interpret): + (JSC::Yarr::Interpreter::Interpreter): + (JSC::Yarr::ByteCompiler::compile): + (JSC::Yarr::byteCompileRegex): + * yarr/RegexInterpreter.h: + (JSC::Yarr::BytecodePattern::BytecodePattern): + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Windows build fix from Chromium/GTK build fix! + + * wtf/PageAllocation.cpp: + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Chromium/GTK build fix + + * wtf/PageAllocation.cpp: + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Build fix for !Mac platforms. + + * Android.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pro: + * JavaScriptCore.vcproj/WTF/WTF.vcproj: + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 43009 - Abstract out page allocation from executable allocators + + It would be great to have a single platform abstraction for block allocation, rather than copy/paste code. + + In this initial implementation I've made Symbian fall back to use malloc/free for non-executable memory. + I think this will match current behaviour for the next client we will want to port across (RegisterFile & + Collector). + + * CMakeListsEfl.txt: + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pro: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * jit/ExecutableAllocator.cpp: + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + (JSC::ExecutableAllocator::isValid): + * jit/ExecutableAllocator.h: + (JSC::ExecutablePool::ExecutablePool): + (JSC::ExecutablePool::poolAllocate): + * jit/ExecutableAllocatorFixedVMPool.cpp: + (JSC::FixedVMPoolAllocator::release): + (JSC::FixedVMPoolAllocator::reuse): + (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator): + (JSC::FixedVMPoolAllocator::alloc): + (JSC::FixedVMPoolAllocator::free): + (JSC::FixedVMPoolAllocator::isValid): + (JSC::FixedVMPoolAllocator::isWithinVMPool): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + * jit/ExecutableAllocatorPosix.cpp: Removed. + * jit/ExecutableAllocatorSymbian.cpp: Removed. + * jit/ExecutableAllocatorWin.cpp: Removed. + * wscript: + * wtf/PageAllocator.cpp: Added. + (WTF::protection): + (WTF::PageAllocation::commit): + (WTF::PageAllocation::decommit): + (WTF::PageAllocator::allocate): + (WTF::PageAllocator::reserve): + (WTF::PageAllocator::deallocate): + (WTF::PageAllocator::pagesize): + * wtf/PageAllocator.h: Added. + (WTF::PageAllocation::PageAllocation): + (WTF::PageAllocation::base): + (WTF::PageAllocation::size): + (WTF::PageAllocation::chunk): + (WTF::PageAllocation::operator!): + (WTF::PageAllocator::): + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Rolling out r64097:64100, oops, more b0rked than I relized by my last changes, sorry! + + * CMakeListsEfl.txt: + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pro: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * jit/ExecutableAllocator.cpp: + (JSC::ExecutableAllocator::reprotectRegion): + (JSC::ExecutableAllocator::cacheFlush): + * jit/ExecutableAllocator.h: + (JSC::ExecutablePool::ExecutablePool): + (JSC::ExecutablePool::poolAllocate): + * jit/ExecutableAllocatorFixedVMPool.cpp: + (JSC::FixedVMPoolAllocator::release): + (JSC::FixedVMPoolAllocator::reuse): + (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator): + (JSC::FixedVMPoolAllocator::alloc): + (JSC::FixedVMPoolAllocator::free): + (JSC::FixedVMPoolAllocator::isValid): + (JSC::FixedVMPoolAllocator::isWithinVMPool): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + * jit/ExecutableAllocatorPosix.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + (JSC::ExecutableAllocator::isValid): + * jit/ExecutableAllocatorSymbian.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + (JSC::ExecutableAllocator::isValid): + * jit/ExecutableAllocatorWin.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + (JSC::ExecutableAllocator::isValid): + * wscript: + * wtf/PageAllocation.cpp: Removed. + * wtf/PageAllocation.h: Removed. + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Speculative !debug build fix II. + + * wtf/PageAllocation.h: + (WTF::PageAllocation::PageAllocation): + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Speculative !debug build fix. + + * wtf/PageAllocation.h: + (WTF::PageAllocation::PageAllocation): + +2010-07-26 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 43009 - Abstract out page allocation from executable allocators + + It would be great to have a single platform abstraction for block allocation, rather than copy/paste code. + + In this initial implementation I've made Symbian fall back to use malloc/free for non-executable memory. + I think this will match current behaviour for the next client we will want to port across (RegisterFile & + Collector). + + * CMakeListsEfl.txt: + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pro: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * jit/ExecutableAllocator.cpp: + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + (JSC::ExecutableAllocator::isValid): + * jit/ExecutableAllocator.h: + (JSC::ExecutablePool::ExecutablePool): + (JSC::ExecutablePool::poolAllocate): + * jit/ExecutableAllocatorFixedVMPool.cpp: + (JSC::FixedVMPoolAllocator::release): + (JSC::FixedVMPoolAllocator::reuse): + (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator): + (JSC::FixedVMPoolAllocator::alloc): + (JSC::FixedVMPoolAllocator::free): + (JSC::FixedVMPoolAllocator::isValid): + (JSC::FixedVMPoolAllocator::isWithinVMPool): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + * jit/ExecutableAllocatorPosix.cpp: Removed. + * jit/ExecutableAllocatorSymbian.cpp: Removed. + * jit/ExecutableAllocatorWin.cpp: Removed. + * wscript: + * wtf/PageAllocator.cpp: Added. + (WTF::protection): + (WTF::PageAllocation::commit): + (WTF::PageAllocation::decommit): + (WTF::PageAllocator::allocate): + (WTF::PageAllocator::reserve): + (WTF::PageAllocator::deallocate): + (WTF::PageAllocator::pagesize): + * wtf/PageAllocator.h: Added. + (WTF::PageAllocation::PageAllocation): + (WTF::PageAllocation::base): + (WTF::PageAllocation::size): + (WTF::PageAllocation::chunk): + (WTF::PageAllocation::operator!): + (WTF::PageAllocator::): + +2009-10-30 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Use the default timeout interval for JS as the HTML tokenizer delay for setHtml() + + This ensures that long-running JavaScript (for example due to a modal alert() dialog), + will not trigger a deferred load after only 500ms (the default tokenizer delay) while + still giving a reasonable timeout (10 seconds) to prevent deadlock. + + https://bugs.webkit.org/show_bug.cgi?id=29381 + + * runtime/TimeoutChecker.h: Add getter for the timeout interval + +2010-07-25 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Kent Tamura. + + [WINCE] Buildfix for JSC in release mode + https://bugs.webkit.org/show_bug.cgi?id=42934 + + * jsc.cpp: Don't use __try on WinCE. + +2010-07-24 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Darin Adler. + + [MSVC] Ensure 4 byte alignment on ARM + https://bugs.webkit.org/show_bug.cgi?id=42935 + + * jit/JITStubs.h: Added #pragma pack(4) around JITStackFrame. + +2010-07-24 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Darin Adler. + + [WINCE] Cleanup defines in Platform.h + https://bugs.webkit.org/show_bug.cgi?id=42933 + + * wtf/Platform.h: + +2010-07-23 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Cleanup glib support (make it optional) + https://bugs.webkit.org/show_bug.cgi?id=42480 + + Remove gobject/GRefPtr.cpp if not using soup/glib. + + * wtf/CMakeListsEfl.txt: + +2010-07-23 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Adam Roben. + + [WINCE] Implement TCSpinLock. + https://bugs.webkit.org/show_bug.cgi?id=41792 + + Implement the SpinLock with InterlockedExchange from the Windows API. + + * wtf/TCSpinLock.h: + (TCMalloc_SpinLock::Lock): + (TCMalloc_SpinLock::Unlock): + (TCMalloc_SpinLock::IsHeld): + (TCMalloc_SpinLock::Init): + (TCMalloc_SlowLock): + +2010-07-22 Csaba Osztrogonác <ossy@webkit.org> + + Unreviewed rolling out r63947 and r63948, because they broke Qt Windows build. + + * jit/JITStubs.cpp: + * jit/JITStubs.h: + +2010-07-22 Gavin Barraclough <barraclough@apple.com> + + Eeeep! r63947 hosed all non-x86 builds! + + * jit/JITStubs.h: + +2010-07-22 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Bug 42818 - [Qt] REGRESSION(63348): jsc is broken + Speculative fix, need fastcall conventions on Qt/Win. + + * jit/JITStubs.cpp: + * jit/JITStubs.h: + +2010-07-22 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Do more constant folding + https://bugs.webkit.org/show_bug.cgi?id=42867 + + Constant fold a few more operations. SunSpider says this is + a win but I suspect that's just code motion at play. + + * parser/ASTBuilder.h: + (JSC::ASTBuilder::makeModNode): + (JSC::ASTBuilder::makeURightShiftNode): + (JSC::ASTBuilder::makeBitOrNode): + (JSC::ASTBuilder::makeBitAndNode): + (JSC::ASTBuilder::makeBitXOrNode): + (JSC::ASTBuilder::makeBinaryNode): + +2010-07-22 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Kent Tamura. + + Error properties of the Global Object are missing the DontEnum attribute + https://bugs.webkit.org/show_bug.cgi?id=28771 + + Add the attributes to become spec compliant. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + 2010-07-20 Steve Falkenburg <sfalken@apple.com> Reviewed by Adam Roben. diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig index 4b363aa..8e33a91 100644 --- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -55,6 +55,7 @@ ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE; ENABLE_FILTERS = ENABLE_FILTERS; ENABLE_FILE_READER = ENABLE_FILE_READER; ENABLE_FILE_WRITER = ; +ENABLE_FILE_SYSTEM = ; ENABLE_GEOLOCATION = ENABLE_GEOLOCATION; ENABLE_ICONDATABASE = ENABLE_ICONDATABASE; ENABLE_IMAGE_RESIZER = ; @@ -85,4 +86,4 @@ ENABLE_XHTMLMP = ; ENABLE_XPATH = ENABLE_XPATH; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(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); +FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(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_FILE_SYSTEM) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_IMAGE_RESIZER) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT); diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index 2749545..c1b6b32 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 = 3; +MINOR_VERSION = 4; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index 9a2886f..98f491c 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -456,6 +456,8 @@ javascriptcore_sources += \ JavaScriptCore/wtf/OwnFastMallocPtr.h \ JavaScriptCore/wtf/OwnPtrCommon.h \ JavaScriptCore/wtf/OwnPtr.h \ + JavaScriptCore/wtf/PageAllocation.cpp \ + JavaScriptCore/wtf/PageAllocation.h \ JavaScriptCore/wtf/PassOwnPtr.h \ JavaScriptCore/wtf/PassRefPtr.h \ JavaScriptCore/wtf/Platform.h \ @@ -526,12 +528,10 @@ javascriptcore_sources += \ if TARGET_WIN32 javascriptcore_sources += \ JavaScriptCore/wtf/ThreadSpecificWin.cpp \ - JavaScriptCore/jit/ExecutableAllocatorWin.cpp \ JavaScriptCore/runtime/MarkStackWin.cpp else javascriptcore_sources += \ JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp \ - JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \ JavaScriptCore/runtime/MarkStackPosix.cpp endif diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi index 066e1ff..9281576 100644 --- a/JavaScriptCore/JavaScriptCore.gypi +++ b/JavaScriptCore/JavaScriptCore.gypi @@ -110,8 +110,6 @@ 'jit/ExecutableAllocator.cpp', 'jit/ExecutableAllocator.h', 'jit/ExecutableAllocatorFixedVMPool.cpp', - 'jit/ExecutableAllocatorPosix.cpp', - 'jit/ExecutableAllocatorWin.cpp', 'jit/JIT.cpp', 'jit/JIT.h', 'jit/JITArithmetic.cpp', @@ -396,6 +394,8 @@ 'wtf/OwnFastMallocPtr.h', 'wtf/OwnPtr.h', 'wtf/OwnPtrCommon.h', + 'wtf/PageAllocation.cpp', + 'wtf/PageAllocation.h', 'wtf/PassOwnPtr.h', 'wtf/PassRefPtr.h', 'wtf/Platform.h', diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro index 84ce83c..2489580 100644 --- a/JavaScriptCore/JavaScriptCore.pro +++ b/JavaScriptCore/JavaScriptCore.pro @@ -94,9 +94,6 @@ SOURCES += \ interpreter/Interpreter.cpp \ interpreter/RegisterFile.cpp \ jit/ExecutableAllocatorFixedVMPool.cpp \ - jit/ExecutableAllocatorPosix.cpp \ - jit/ExecutableAllocatorSymbian.cpp \ - jit/ExecutableAllocatorWin.cpp \ jit/ExecutableAllocator.cpp \ jit/JITArithmetic.cpp \ jit/JITArithmetic32_64.cpp \ @@ -215,6 +212,7 @@ SOURCES += \ wtf/qt/MainThreadQt.cpp \ wtf/qt/StringQt.cpp \ wtf/qt/ThreadingQt.cpp \ + wtf/PageAllocation.cpp \ wtf/RandomNumber.cpp \ wtf/RefCountedLeakCounter.cpp \ wtf/symbian/BlockAllocatorSymbian.cpp \ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index dbddfe0..7819f99 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -1641,10 +1641,6 @@ >
</File>
<File
- RelativePath="..\..\jit\ExecutableAllocatorWin.cpp"
- >
- </File>
- <File
RelativePath="..\..\jit\JIT.cpp"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj index f7652df..7f18f7e 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj @@ -429,6 +429,14 @@ >
</File>
<File
+ RelativePath="..\..\wtf\PageAllocation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\PageAllocation.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\PassOwnPtr.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index 562b4a1..9e86120 100644 --- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -198,10 +198,13 @@ 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; }; 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */; }; 8626BECF11928E3900782FAB /* StringStatics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8626BECE11928E3900782FAB /* StringStatics.cpp */; }; + 8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8627E5E911F1281900A313B5 /* PageAllocation.cpp */; }; + 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8627E5EA11F1281900A313B5 /* PageAllocation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; }; 86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; }; 865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; }; + 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA00117CEFD100B908B1 /* AtomicString.cpp */; }; 868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA01117CEFD100B908B1 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; }; 868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -312,7 +315,6 @@ A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; }; A76EE6590FAE59D5003F069A /* NativeFunctionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; }; A7795590101A74D500114E55 /* MarkStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A779558F101A74D500114E55 /* MarkStack.h */; settings = {ATTRIBUTES = (Private, ); }; }; - A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */; }; A783A0D111A36DCA00563D20 /* JSObjectWithGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A783A0D011A36DCA00563D20 /* JSObjectWithGlobalObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; A783A2AB11A5BE8400563D20 /* JSObjectWithGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A783A2AA11A5BE8400563D20 /* JSObjectWithGlobalObject.cpp */; }; A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; }; @@ -767,10 +769,13 @@ 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86_64.h; sourceTree = "<group>"; }; 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; }; 8626BECE11928E3900782FAB /* StringStatics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringStatics.cpp; path = text/StringStatics.cpp; sourceTree = "<group>"; }; + 8627E5E911F1281900A313B5 /* PageAllocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageAllocation.cpp; sourceTree = "<group>"; }; + 8627E5EA11F1281900A313B5 /* PageAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageAllocation.h; sourceTree = "<group>"; }; 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; }; 86565740115BE3DA00291F40 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = text/CString.cpp; sourceTree = "<group>"; }; 86565741115BE3DA00291F40 /* CString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CString.h; path = text/CString.h; sourceTree = "<group>"; }; 865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; }; + 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BumpPointerAllocator.h; sourceTree = "<group>"; }; 867FC35F11B763950025105E /* JavaScriptCore.JSVALUE32_64only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE32_64only.exp; sourceTree = "<group>"; }; 867FC36011B763950025105E /* JavaScriptCore.JSVALUE32only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE32only.exp; sourceTree = "<group>"; }; 867FC36111B763950025105E /* JavaScriptCore.JSVALUE64only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE64only.exp; sourceTree = "<group>"; }; @@ -812,7 +817,6 @@ 86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARM.h; sourceTree = "<group>"; }; 86D3B3C110159D7F002865E7 /* LinkBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkBuffer.h; sourceTree = "<group>"; }; 86D3B3C210159D7F002865E7 /* RepatchBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RepatchBuffer.h; sourceTree = "<group>"; }; - 86DB645F0F954E9100D7D921 /* ExecutableAllocatorWin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorWin.cpp; sourceTree = "<group>"; }; 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; }; 86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; }; 86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; }; @@ -914,7 +918,6 @@ A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; }; A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeFunctionWrapper.h; sourceTree = "<group>"; }; A779558F101A74D500114E55 /* MarkStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStack.h; sourceTree = "<group>"; }; - A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorPosix.cpp; sourceTree = "<group>"; }; A783A0D011A36DCA00563D20 /* JSObjectWithGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectWithGlobalObject.h; sourceTree = "<group>"; }; A783A2AA11A5BE8400563D20 /* JSObjectWithGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObjectWithGlobalObject.cpp; sourceTree = "<group>"; }; A791EF260F11E07900AE1F68 /* JSByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSByteArray.h; sourceTree = "<group>"; }; @@ -1253,8 +1256,6 @@ A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */, A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */, 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */, - A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */, - 86DB645F0F954E9100D7D921 /* ExecutableAllocatorWin.cpp */, 1429D92D0ED22D7000B89619 /* JIT.cpp */, 1429D92E0ED22D7000B89619 /* JIT.h */, 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */, @@ -1405,6 +1406,7 @@ 65E217B708E7EECC0023E5F6 /* Assertions.h */, BC5F7BBB11823B590052C02C /* Atomics.h */, E1A596370DE3E1C300C17E37 /* AVLTree.h */, + 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */, A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */, A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */, 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */, @@ -1446,6 +1448,8 @@ 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */, 9303F567099118FA00AD71B8 /* OwnPtr.h */, 440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */, + 8627E5E911F1281900A313B5 /* PageAllocation.cpp */, + 8627E5EA11F1281900A313B5 /* PageAllocation.h */, 44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */, 6580F795094070560082C219 /* PassRefPtr.h */, 65D6D87E09B5A32E0002E4D7 /* Platform.h */, @@ -1920,6 +1924,7 @@ BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */, 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */, BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */, + 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */, A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */, 969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */, 869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */, @@ -2082,6 +2087,7 @@ 0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */, BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */, 4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */, + 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */, BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */, 93052C350FB792190048FDC3 /* ParserArena.h in Headers */, 44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */, @@ -2496,7 +2502,6 @@ 86CA032E1038E8440028A609 /* Executable.cpp in Sources */, A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */, 86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */, - A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */, 14F8BA3E107EC886009892DC /* FastMalloc.cpp in Sources */, 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */, 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */, @@ -2627,6 +2632,7 @@ E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */, 868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */, 86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */, + 8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/JavaScriptCore/jit/ExecutableAllocator.cpp b/JavaScriptCore/jit/ExecutableAllocator.cpp index 5e10e86..86c24fd 100644 --- a/JavaScriptCore/jit/ExecutableAllocator.cpp +++ b/JavaScriptCore/jit/ExecutableAllocator.cpp @@ -33,7 +33,48 @@ namespace JSC { size_t ExecutableAllocator::pageSize = 0; +#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) + +void ExecutableAllocator::intializePageSize() +{ +#if CPU(ARMV5_OR_LOWER) + // The moving memory model (as used in ARMv5 and earlier platforms) + // on Symbian OS limits the number of chunks for each process to 16. + // To mitigate this limitation increase the pagesize to allocate + // fewer, larger chunks. Set the page size to 256 Kb to compensate + // for moving memory model limitation + ExecutableAllocator::pageSize = 256 * 1024; +#else + ExecutableAllocator::pageSize = PageAllocation::pagesize(); +#endif +} + +ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size) +{ + PageAllocation allocation = PageAllocation::allocate(size, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true); + if (!allocation) + CRASH(); + return allocation; +} + +void ExecutablePool::systemRelease(ExecutablePool::Allocation& allocation) +{ + allocation.deallocate(); +} + +bool ExecutableAllocator::isValid() const +{ + return true; +} + +#endif + #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) + +#if OS(WINDOWS) || OS(SYMBIAN) +#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." +#endif + void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSeting setting) { if (!pageSize) @@ -52,9 +93,11 @@ void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSe mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : PROTECTION_FLAGS_RX); } + #endif #if CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(RVCT) + __asm void ExecutableAllocator::cacheFlush(void* code, size_t size) { ARM @@ -67,6 +110,7 @@ __asm void ExecutableAllocator::cacheFlush(void* code, size_t size) pop {r7} bx lr } + #endif } diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h index 8fd6b71..f8e991f 100644 --- a/JavaScriptCore/jit/ExecutableAllocator.h +++ b/JavaScriptCore/jit/ExecutableAllocator.h @@ -28,6 +28,7 @@ #include <stddef.h> // for ptrdiff_t #include <limits> #include <wtf/Assertions.h> +#include <wtf/PageAllocation.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/UnusedParam.h> @@ -58,9 +59,9 @@ extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLeng #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) #define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE) #define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC) -#define INITIAL_PROTECTION_FLAGS PROTECTION_FLAGS_RX +#define EXECUTABLE_POOL_WRITABLE false #else -#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC) +#define EXECUTABLE_POOL_WRITABLE true #endif namespace JSC { @@ -85,13 +86,7 @@ namespace JSC { class ExecutablePool : public RefCounted<ExecutablePool> { private: - struct Allocation { - char* pages; - size_t size; -#if OS(SYMBIAN) - RChunk* chunk; -#endif - }; + typedef PageAllocation Allocation; typedef Vector<Allocation, 2> AllocationList; public: @@ -121,8 +116,8 @@ public: ~ExecutablePool() { - AllocationList::const_iterator end = m_pools.end(); - for (AllocationList::const_iterator ptr = m_pools.begin(); ptr != end; ++ptr) + AllocationList::iterator end = m_pools.end(); + for (AllocationList::iterator ptr = m_pools.begin(); ptr != end; ++ptr) ExecutablePool::systemRelease(*ptr); } @@ -130,7 +125,7 @@ public: private: static Allocation systemAlloc(size_t n); - static void systemRelease(const Allocation& alloc); + static void systemRelease(Allocation& alloc); ExecutablePool(size_t n); @@ -204,8 +199,8 @@ public: #elif CPU(MIPS) static void cacheFlush(void* code, size_t size) { -#if COMPILER(GCC) && (GCC_VERSION >= 40300) -#if WTF_MIPS_ISA_REV(2) && (GCC_VERSION < 40403) +#if COMPILER(GCC) && GCC_VERSION_AT_LEAST(4,3,0) +#if WTF_MIPS_ISA_REV(2) && GCC_VERSION_AT_LEAST(4,4,3) int lineSize; asm("rdhwr %0, $1" : "=r" (lineSize)); // @@ -296,7 +291,7 @@ inline ExecutablePool::ExecutablePool(size_t n) size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE); Allocation mem = systemAlloc(allocSize); m_pools.append(mem); - m_freePtr = mem.pages; + m_freePtr = static_cast<char*>(mem.base()); if (!m_freePtr) CRASH(); // Failed to allocate m_end = m_freePtr + allocSize; @@ -307,18 +302,18 @@ inline void* ExecutablePool::poolAllocate(size_t n) size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE); Allocation result = systemAlloc(allocSize); - if (!result.pages) + if (!result.base()) CRASH(); // Failed to allocate ASSERT(m_end >= m_freePtr); if ((allocSize - n) > static_cast<size_t>(m_end - m_freePtr)) { // Replace allocation pool - m_freePtr = result.pages + n; - m_end = result.pages + allocSize; + m_freePtr = static_cast<char*>(result.base()) + n; + m_end = static_cast<char*>(result.base()) + allocSize; } m_pools.append(result); - return result.pages; + return result.base(); } } diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp index 65c9c13..421c34b 100644 --- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp +++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp @@ -124,30 +124,17 @@ class FixedVMPoolAllocator // The free list is stored in a sorted tree. typedef AVLTree<AVLTreeAbstractorForFreeList, 40> SizeSortedFreeTree; - // Use madvise as apropriate to prevent freed pages from being spilled, - // and to attempt to ensure that used memory is reported correctly. -#if HAVE(MADV_FREE_REUSE) void release(void* position, size_t size) { - while (madvise(position, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } + m_allocation.decommit(position, size); } void reuse(void* position, size_t size) { - while (madvise(position, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { } - } -#elif HAVE(MADV_DONTNEED) - void release(void* position, size_t size) - { - while (madvise(position, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { } + bool okay = m_allocation.commit(position, size, EXECUTABLE_POOL_WRITABLE, true); + ASSERT_UNUSED(okay, okay); } - void reuse(void*, size_t) {} -#else - void release(void*, size_t) {} - void reuse(void*, size_t) {} -#endif - // All addition to the free list should go through this method, rather than // calling insert directly, to avoid multiple entries beging added with the // same key. All nodes being added should be singletons, they should not @@ -288,7 +275,6 @@ public: FixedVMPoolAllocator(size_t commonSize, size_t totalHeapSize) : m_commonSize(commonSize) , m_countFreedSinceLastCoalesce(0) - , m_totalHeapSize(totalHeapSize) { // Cook up an address to allocate at, using the following recipe: // 17 bits of zero, stay in userspace kids. @@ -299,36 +285,67 @@ public: // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus // 2^24, which should put up somewhere in the middle of usespace (in the address range // 0x200000000000 .. 0x5fffffffffff). - intptr_t randomLocation = 0; #if VM_POOL_ASLR + intptr_t randomLocation = 0; randomLocation = arc4random() & ((1 << 25) - 1); randomLocation += (1 << 24); randomLocation <<= 21; + m_allocation = PageAllocation::reserveAt(reinterpret_cast<void*>(randomLocation), false, totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true); +#else + m_allocation = PageAllocation::reserve(totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true); #endif - m_base = mmap(reinterpret_cast<void*>(randomLocation), m_totalHeapSize, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); - - if (m_base) { - // For simplicity, we keep all memory in m_freeList in a 'released' state. - // This means that we can simply reuse all memory when allocating, without - // worrying about it's previous state, and also makes coalescing m_freeList - // simpler since we need not worry about the possibility of coalescing released - // chunks with non-released ones. - release(m_base, m_totalHeapSize); - m_freeList.insert(new FreeListEntry(m_base, m_totalHeapSize)); - } + + if (!!m_allocation) + m_freeList.insert(new FreeListEntry(m_allocation.base(), m_allocation.size())); #if !ENABLE(INTERPRETER) else CRASH(); #endif } - void* alloc(size_t size) + PageAllocation alloc(size_t size) + { + return PageAllocation(allocInternal(size), size, m_allocation); + } + + void free(PageAllocation allocation) + { + void* pointer = allocation.base(); + size_t size = allocation.size(); + + ASSERT(!!m_allocation); + // Call release to report to the operating system that this + // memory is no longer in use, and need not be paged out. + ASSERT(isWithinVMPool(pointer, size)); + release(pointer, size); + + // Common-sized allocations are stored in the m_commonSizedAllocations + // vector; all other freed chunks are added to m_freeList. + if (size == m_commonSize) + m_commonSizedAllocations.append(pointer); + else + addToFreeList(new FreeListEntry(pointer, size)); + + // Do some housekeeping. Every time we reach a point that + // 16MB of allocations have been freed, sweep m_freeList + // coalescing any neighboring fragments. + m_countFreedSinceLastCoalesce += size; + if (m_countFreedSinceLastCoalesce >= COALESCE_LIMIT) { + m_countFreedSinceLastCoalesce = 0; + coalesceFreeSpace(); + } + } + + bool isValid() const { return !!m_allocation; } + +private: + void* allocInternal(size_t size) { #if ENABLE(INTERPRETER) - if (!m_base) + if (!m_allocation) return 0; #else - ASSERT(m_base); + ASSERT(!!m_allocation); #endif void* result; @@ -390,39 +407,10 @@ public: return result; } - void free(void* pointer, size_t size) - { - ASSERT(m_base); - // Call release to report to the operating system that this - // memory is no longer in use, and need not be paged out. - ASSERT(isWithinVMPool(pointer, size)); - release(pointer, size); - - // Common-sized allocations are stored in the m_commonSizedAllocations - // vector; all other freed chunks are added to m_freeList. - if (size == m_commonSize) - m_commonSizedAllocations.append(pointer); - else - addToFreeList(new FreeListEntry(pointer, size)); - - // Do some housekeeping. Every time we reach a point that - // 16MB of allocations have been freed, sweep m_freeList - // coalescing any neighboring fragments. - m_countFreedSinceLastCoalesce += size; - if (m_countFreedSinceLastCoalesce >= COALESCE_LIMIT) { - m_countFreedSinceLastCoalesce = 0; - coalesceFreeSpace(); - } - } - - bool isValid() const { return !!m_base; } - -private: - #ifndef NDEBUG bool isWithinVMPool(void* pointer, size_t size) { - return pointer >= m_base && (reinterpret_cast<char*>(pointer) + size <= reinterpret_cast<char*>(m_base) + m_totalHeapSize); + return pointer >= m_allocation.base() && (reinterpret_cast<char*>(pointer) + size <= reinterpret_cast<char*>(m_allocation.base()) + m_allocation.size()); } #endif @@ -436,8 +424,7 @@ private: // This is used for housekeeping, to trigger defragmentation of the freed lists. size_t m_countFreedSinceLastCoalesce; - void* m_base; - size_t m_totalHeapSize; + PageAllocation m_allocation; }; void ExecutableAllocator::intializePageSize() @@ -459,18 +446,15 @@ bool ExecutableAllocator::isValid() const ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size) { SpinLockHolder lock_holder(&spinlock); - ASSERT(allocator); - ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocator->alloc(size)), size}; - return alloc; + return allocator->alloc(size); } -void ExecutablePool::systemRelease(const ExecutablePool::Allocation& allocation) +void ExecutablePool::systemRelease(ExecutablePool::Allocation& allocation) { SpinLockHolder lock_holder(&spinlock); - ASSERT(allocator); - allocator->free(allocation.pages, allocation.size); + allocator->free(allocation); } } diff --git a/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp b/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp deleted file mode 100644 index a841d32..0000000 --- a/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include "ExecutableAllocator.h" - -#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && !OS(WINDOWS) && !OS(SYMBIAN) - -#include <sys/mman.h> -#include <unistd.h> -#include <wtf/VMTags.h> - -namespace JSC { - -void ExecutableAllocator::intializePageSize() -{ - ExecutableAllocator::pageSize = getpagesize(); -} - -ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) -{ - void* allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); - if (allocation == MAP_FAILED) - CRASH(); - ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; - return alloc; -} - -void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) -{ - int result = munmap(alloc.pages, alloc.size); - ASSERT_UNUSED(result, !result); -} - -bool ExecutableAllocator::isValid() const -{ - return true; -} - -} - -#endif diff --git a/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp deleted file mode 100644 index 8b0553d..0000000 --- a/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2009 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 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 "ExecutableAllocator.h" - -#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && OS(SYMBIAN) - -#include <e32hal.h> -#include <e32std.h> - -// Set the page size to 256 Kb to compensate for moving memory model limitation -const size_t MOVING_MEM_PAGE_SIZE = 256 * 1024; - -namespace JSC { - -void ExecutableAllocator::intializePageSize() -{ -#if CPU(ARMV5_OR_LOWER) - // The moving memory model (as used in ARMv5 and earlier platforms) - // on Symbian OS limits the number of chunks for each process to 16. - // To mitigate this limitation increase the pagesize to - // allocate less of larger chunks. - ExecutableAllocator::pageSize = MOVING_MEM_PAGE_SIZE; -#else - TInt page_size; - UserHal::PageSizeInBytes(page_size); - ExecutableAllocator::pageSize = page_size; -#endif -} - -ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) -{ - RChunk* codeChunk = new RChunk(); - - TInt errorCode = codeChunk->CreateLocalCode(n, n); - - char* allocation = reinterpret_cast<char*>(codeChunk->Base()); - if (!allocation) - CRASH(); - ExecutablePool::Allocation alloc = { allocation, n, codeChunk }; - return alloc; -} - -void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) -{ - alloc.chunk->Close(); - delete alloc.chunk; -} - -bool ExecutableAllocator::isValid() const -{ - return true; -} - -#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) -#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." -#endif - -} - -#endif // HAVE(ASSEMBLER) diff --git a/JavaScriptCore/jit/ExecutableAllocatorWin.cpp b/JavaScriptCore/jit/ExecutableAllocatorWin.cpp deleted file mode 100644 index 2b13529..0000000 --- a/JavaScriptCore/jit/ExecutableAllocatorWin.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include "ExecutableAllocator.h" - -#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && OS(WINDOWS) - -#include "windows.h" - -namespace JSC { - -void ExecutableAllocator::intializePageSize() -{ - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - ExecutableAllocator::pageSize = system_info.dwPageSize; -} - -ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) -{ - void* allocation = VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if (!allocation) - CRASH(); - ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocation), n}; - return alloc; -} - -void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) -{ - VirtualFree(alloc.pages, 0, MEM_RELEASE); -} - -bool ExecutableAllocator::isValid() const -{ - return true; -} - -#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) -#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." -#endif - -} - -#endif // HAVE(ASSEMBLER) diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h index f9be930..d398d51 100644 --- a/JavaScriptCore/jit/JIT.h +++ b/JavaScriptCore/jit/JIT.h @@ -783,7 +783,7 @@ namespace JSC { void emit_op_to_primitive(Instruction*); void emit_op_unexpected_load(Instruction*); void emit_op_urshift(Instruction*); -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) void softModulo(); #endif diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp index 0f6d290..a9d0bcd 100644 --- a/JavaScriptCore/jit/JITArithmetic.cpp +++ b/JavaScriptCore/jit/JITArithmetic.cpp @@ -1196,7 +1196,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) emitGetVirtualRegisters(op1, regT0, op2, regT2); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT2); @@ -1216,7 +1216,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) unsigned result = currentInstruction[1].u.operand; unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; diff --git a/JavaScriptCore/jit/JITArithmetic32_64.cpp b/JavaScriptCore/jit/JITArithmetic32_64.cpp index 232e287..5a69d5a 100644 --- a/JavaScriptCore/jit/JITArithmetic32_64.cpp +++ b/JavaScriptCore/jit/JITArithmetic32_64.cpp @@ -1363,7 +1363,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) emitLoad2(op1, regT1, regT0, op2, regT3, regT2); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); @@ -1383,7 +1383,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) unsigned result = currentInstruction[1].u.operand; unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index 949dee3..852de4e 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -45,7 +45,7 @@ namespace JSC { void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines) { -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) Label softModBegin = align(); softModulo(); #endif @@ -184,7 +184,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable trampolines->ctiVirtualConstruct = trampolineAt(finalCode, virtualConstructBegin); trampolines->ctiNativeCall = trampolineAt(finalCode, nativeCallThunk); trampolines->ctiNativeConstruct = trampolineAt(finalCode, nativeConstructThunk); -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin); #endif #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) @@ -1531,7 +1531,7 @@ void JIT::emit_op_new_regexp(Instruction* currentInstruction) } // For both JSValue32_64 and JSValue32 -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) #if CPU(ARM_TRADITIONAL) void JIT::softModulo() { diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp index 658ebc5..5622e9c 100644 --- a/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -42,7 +42,7 @@ namespace JSC { void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines) { -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) Label softModBegin = align(); softModulo(); #endif @@ -187,7 +187,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); trampolines->ctiVirtualConstructLink = trampolineAt(finalCode, virtualConstructLinkBegin); #endif -#if ENABLE(JIT_OPTIMIZE_MOD) +#if ENABLE(JIT_USE_SOFT_MODULO) trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin); #endif } diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index ba9e15f..306e475 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -171,6 +171,10 @@ namespace JSC { ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; #elif CPU(ARM_TRADITIONAL) +#if COMPILER(MSVC) +#pragma pack(push) +#pragma pack(4) +#endif // COMPILER(MSVC) struct JITStackFrame { JITStubArg padding; // Unused JITStubArg args[7]; @@ -195,6 +199,9 @@ namespace JSC { // When JIT code makes a call, it pushes its return address just below the rest of the stack. ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif // COMPILER(MSVC) #elif CPU(MIPS) struct JITStackFrame { void* reserved; // Unused diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp index c91bcb3..03bc411 100644 --- a/JavaScriptCore/jsc.cpp +++ b/JavaScriptCore/jsc.cpp @@ -308,7 +308,7 @@ EncodedJSValue JSC_HOST_CALL functionQuit(ExecState* exec) // be in a separate main function because the jscmain function requires object // unwinding. -#if COMPILER(MSVC) && !defined(_DEBUG) +#if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE) #define TRY __try { #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; } #else diff --git a/JavaScriptCore/parser/ASTBuilder.h b/JavaScriptCore/parser/ASTBuilder.h index 3b7ffb5..f627756 100644 --- a/JavaScriptCore/parser/ASTBuilder.h +++ b/JavaScriptCore/parser/ASTBuilder.h @@ -124,10 +124,15 @@ public: ExpressionNode* makeBitwiseNotNode(ExpressionNode*); ExpressionNode* makeMultNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* makeDivNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); + ExpressionNode* makeModNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* makeAddNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* makeSubNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); + ExpressionNode* makeBitXOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); + ExpressionNode* makeBitAndNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); + ExpressionNode* makeBitOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* makeLeftShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* makeRightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); + ExpressionNode* makeURightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); ExpressionNode* createLogicalNot(ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(m_globalData, expr); } ExpressionNode* createUnaryPlus(ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(m_globalData, expr); } @@ -690,6 +695,16 @@ ExpressionNode* ASTBuilder::makeDivNode(ExpressionNode* expr1, ExpressionNode* e return new (m_globalData) DivNode(m_globalData, expr1, expr2, rightHasAssignments); } +ExpressionNode* ASTBuilder::makeModNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +{ + expr1 = expr1->stripUnaryPlus(); + expr2 = expr2->stripUnaryPlus(); + + if (expr1->isNumber() && expr2->isNumber()) + return createNumber(fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value())); + return new (m_globalData) ModNode(m_globalData, expr1, expr2, rightHasAssignments); +} + ExpressionNode* ASTBuilder::makeAddNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) @@ -721,6 +736,34 @@ ExpressionNode* ASTBuilder::makeRightShiftNode(ExpressionNode* expr1, Expression return new (m_globalData) RightShiftNode(m_globalData, expr1, expr2, rightHasAssignments); } +ExpressionNode* ASTBuilder::makeURightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +{ + if (expr1->isNumber() && expr2->isNumber()) + return createNumber(toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (m_globalData) UnsignedRightShiftNode(m_globalData, expr1, expr2, rightHasAssignments); +} + +ExpressionNode* ASTBuilder::makeBitOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +{ + if (expr1->isNumber() && expr2->isNumber()) + return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value())); + return new (m_globalData) BitOrNode(m_globalData, expr1, expr2, rightHasAssignments); +} + +ExpressionNode* ASTBuilder::makeBitAndNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +{ + if (expr1->isNumber() && expr2->isNumber()) + return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value())); + return new (m_globalData) BitAndNode(m_globalData, expr1, expr2, rightHasAssignments); +} + +ExpressionNode* ASTBuilder::makeBitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +{ + if (expr1->isNumber() && expr2->isNumber()) + return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value())); + return new (m_globalData) BitXOrNode(m_globalData, expr1, expr2, rightHasAssignments); +} + ExpressionNode* ASTBuilder::makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end) { if (!func->isLocation()) @@ -763,13 +806,13 @@ ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, Bina return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalAnd); case BITOR: - return new (m_globalData) BitOrNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); + return makeBitOrNode(lhs.first, rhs.first, rhs.second.hasAssignment); case BITXOR: - return new (m_globalData) BitXOrNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); + return makeBitXOrNode(lhs.first, rhs.first, rhs.second.hasAssignment); case BITAND: - return new (m_globalData) BitAndNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); + return makeBitAndNode(lhs.first, rhs.first, rhs.second.hasAssignment); case EQEQ: return new (m_globalData) EqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); @@ -814,7 +857,7 @@ ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, Bina return makeRightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment); case URSHIFT: - return new (m_globalData) UnsignedRightShiftNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); + return makeURightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment); case PLUS: return makeAddNode(lhs.first, rhs.first, rhs.second.hasAssignment); @@ -829,7 +872,7 @@ ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, Bina return makeDivNode(lhs.first, rhs.first, rhs.second.hasAssignment); case MOD: - return new (m_globalData) ModNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); + return makeModNode(lhs.first, rhs.first, rhs.second.hasAssignment); } CRASH(); return 0; diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog index 448a59e..e80493b 100644 --- a/JavaScriptCore/qt/ChangeLog +++ b/JavaScriptCore/qt/ChangeLog @@ -1,3 +1,146 @@ +2010-07-27 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Update the QScriptValue autotests suite. + + QScriptValue generated files were updated, changes are: + - More tested values (for example QSE::newObject() and QSE::newArray()) + - Tested values are recreated before each test and are not reused. + The change implies better code coverage and some expected result changes. + - A new test to check copy and assign functions. + - Tests are using standard QTestLib interface, without any custom macros. + + [Qt] Improve test coverage for the QScriptValue + https://bugs.webkit.org/show_bug.cgi?id=42366 + + * tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::tst_QScriptValue): + (tst_QScriptValue::~tst_QScriptValue): + (tst_QScriptValue::assignAndCopyConstruct_data): + (tst_QScriptValue::assignAndCopyConstruct): + * tests/qscriptvalue/tst_qscriptvalue.h: + * tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp: + (tst_QScriptValue::equals_data): + (tst_QScriptValue::equals): + (tst_QScriptValue::strictlyEquals_data): + (tst_QScriptValue::strictlyEquals): + (tst_QScriptValue::instanceOf_data): + (tst_QScriptValue::instanceOf): + * tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp: + (tst_QScriptValue::initScriptValues): + * tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp: + (tst_QScriptValue::isValid_data): + (tst_QScriptValue::isValid): + (tst_QScriptValue::isBool_data): + (tst_QScriptValue::isBool): + (tst_QScriptValue::isBoolean_data): + (tst_QScriptValue::isBoolean): + (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::isArray_data): + (tst_QScriptValue::isArray): + (tst_QScriptValue::isError_data): + (tst_QScriptValue::isError): + * tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp: + (tst_QScriptValue::toString_data): + (tst_QScriptValue::toString): + (tst_QScriptValue::toNumber_data): + (tst_QScriptValue::toNumber): + (tst_QScriptValue::toBool_data): + (tst_QScriptValue::toBool): + (tst_QScriptValue::toBoolean_data): + (tst_QScriptValue::toBoolean): + (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): + +2010-07-27 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Implement QScriptEngine::newFunction() parts that doesn't depend on QScriptContext + https://bugs.webkit.org/show_bug.cgi?id=42174 + + Since our function can be called in Javascript both as a function + and as a constructor, we couldn't use the existing + JSObjectMakeFunctionWithCallback() and JSObjectMakeConstructor(). + + Instead, a JSClassRef was created, implementing the needed + callbacks (the callAsConstructor is not there yet because its + behaviour depends on QScriptContext). + + For the moment, QScriptContext is defined as a void type, since we + still don't use it. + + The variant of newFunction() that also takes an external argument + was also implemented. The details of implementation were added to + the qscriptfunction{.c,_p.h} files. + + This commit also adds tests, some of them from Qt's upstream. + + * api/QtScript.pro: + * api/qscriptengine.cpp: + (QScriptEngine::newFunction): + * api/qscriptengine.h: + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + (QScriptEnginePrivate::newFunction): + * api/qscriptengine_p.h: + * api/qscriptfunction.cpp: Added. + (qt_NativeFunction_finalize): + (qt_NativeFunction_callAsFunction): + (qt_NativeFunctionWithArg_finalize): + (qt_NativeFunctionWithArg_callAsFunction): + * api/qscriptfunction_p.h: Added. + (QNativeFunctionData::QNativeFunctionData): + (QNativeFunctionWithArgData::QNativeFunctionWithArgData): + * api/qscriptoriginalglobalobject_p.h: + (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): + (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): + (QScriptOriginalGlobalObject::functionPrototype): + * tests/qscriptengine/tst_qscriptengine.cpp: + (myFunction): + (myFunctionWithArg): + (myFunctionThatReturns): + (myFunctionThatReturnsWithoutEngine): + (myFunctionThatReturnsWrongEngine): + (tst_QScriptEngine::newFunction): + +2010-07-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + QScriptValue::equals benchmark crash fix. + + Patch changes QScriptValue::equals implementation to cover + more edge cases. + + Problem exposes an issue in our autotests (all values got + bound to an engine too fast - bug 42366). + + [Qt] QScriptValue::equals asserts + https://bugs.webkit.org/show_bug.cgi?id=42363 + + * api/qscriptvalue_p.h: + (QScriptValuePrivate::equals): + 2010-07-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro index c2c6f83..490758c 100644 --- a/JavaScriptCore/qt/api/QtScript.pro +++ b/JavaScriptCore/qt/api/QtScript.pro @@ -28,6 +28,7 @@ SOURCES += $$PWD/qscriptengine.cpp \ $$PWD/qscriptstring.cpp \ $$PWD/qscriptprogram.cpp \ $$PWD/qscriptsyntaxcheckresult.cpp \ + $$PWD/qscriptfunction.cpp HEADERS += $$PWD/qtscriptglobal.h \ $$PWD/qscriptengine.h \ @@ -43,7 +44,7 @@ HEADERS += $$PWD/qtscriptglobal.h \ $$PWD/qscriptprogram_p.h \ $$PWD/qscriptsyntaxcheckresult.h \ $$PWD/qscriptoriginalglobalobject_p.h \ - + $$PWD/qscriptfunction_p.h !static: DEFINES += QT_MAKEDLL diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp index 4b2319b..7ef7c8e 100644 --- a/JavaScriptCore/qt/api/qscriptengine.cpp +++ b/JavaScriptCore/qt/api/qscriptengine.cpp @@ -258,6 +258,93 @@ QScriptValue QScriptEngine::undefinedValue() } /*! + Creates a QScriptValue that wraps a native (C++) function. \a fun + must be a C++ function with signature QScriptEngine::FunctionSignature. + \a length is the number of arguments that \a fun expects; this becomes + the \c{length} property of the created QScriptValue. + + Note that \a length only gives an indication of the number of + arguments that the function expects; an actual invocation of a + function can include any number of arguments. You can check the + \l{QScriptContext::argumentCount()}{argumentCount()} of the + QScriptContext associated with the invocation to determine the + actual number of arguments passed. + + A \c{prototype} property is automatically created for the resulting + function object, to provide for the possibility that the function + will be used as a constructor. + + By combining newFunction() and the property flags + QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you + can create script object properties that behave like normal + properties in script code, but are in fact accessed through + functions (analogous to how properties work in \l{Qt's Property + System}). Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11 + + When the property \c{foo} of the script object is subsequently + accessed in script code, \c{getSetFoo()} will be invoked to handle + the access. In this particular case, we chose to store the "real" + value of \c{foo} as a property of the accessor function itself; you + are of course free to do whatever you like in this function. + + In the above example, a single native function was used to handle + both reads and writes to the property; the argument count is used to + determine if we are handling a read or write. You can also use two + separate functions; just specify the relevant flag + (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when + setting the property, e.g.: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12 + + \sa QScriptValue::call() +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length)); +} + +/*! + Creates a constructor function from \a fun, with the given \a length. + The \c{prototype} property of the resulting function is set to be the + given \a prototype. The \c{constructor} property of \a prototype is + set to be the resulting function. + + When a function is called as a constructor (e.g. \c{new Foo()}), the + `this' object associated with the function call is the new object + that the function is expected to initialize; the prototype of this + default constructed object will be the function's public + \c{prototype} property. If you always want the function to behave as + a constructor (e.g. \c{Foo()} should also create a new object), or + if you need to create your own object rather than using the default + `this' object, you should make sure that the prototype of your + object is set correctly; either by setting it manually, or, when + wrapping a custom type, by having registered the defaultPrototype() + of that type. Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9 + + To wrap a custom type and provide a constructor for it, you'd typically + do something like this: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length)); +} + +/*! + \internal + \since 4.4 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg)); +} + +/*! Creates a QtScript object of class Object. The prototype of the created object will be the Object @@ -294,3 +381,23 @@ QScriptValue QScriptEngine::globalObject() const { return QScriptValuePrivate::get(d_ptr->globalObject()); } + +/*! + \typedef QScriptEngine::FunctionSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ + +/*! + \typedef QScriptEngine::FunctionWithArgSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h index 1a87a37..b85dc52 100644 --- a/JavaScriptCore/qt/api/qscriptengine.h +++ b/JavaScriptCore/qt/api/qscriptengine.h @@ -30,6 +30,9 @@ class QScriptValue; class QScriptEnginePrivate; +// FIXME: Remove this once QScriptContext is properly defined. +typedef void QScriptContext; + // Internal typedef typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr; @@ -56,6 +59,14 @@ public: QScriptValue nullValue(); QScriptValue undefinedValue(); + + typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *); + typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *); + + QScriptValue newFunction(FunctionSignature fun, int length = 0); + QScriptValue newFunction(FunctionSignature fun, const QScriptValue& prototype, int length = 0); + QScriptValue newFunction(FunctionWithArgSignature fun, void* arg); + QScriptValue newObject(); QScriptValue newArray(uint length = 0); QScriptValue globalObject() const; diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp index e3311ed..a708a34 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.cpp +++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -21,6 +21,7 @@ #include "qscriptengine_p.h" +#include "qscriptfunction_p.h" #include "qscriptprogram_p.h" #include "qscriptvalue_p.h" @@ -33,11 +34,15 @@ QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine) , m_context(JSGlobalContextCreate(0)) , m_exception(0) , m_originalGlobalObject(m_context) + , m_nativeFunctionClass(JSClassCreate(&qt_NativeFunctionClass)) + , m_nativeFunctionWithArgClass(JSClassCreate(&qt_NativeFunctionWithArgClass)) { } QScriptEnginePrivate::~QScriptEnginePrivate() { + JSClassRelease(m_nativeFunctionClass); + JSClassRelease(m_nativeFunctionWithArgClass); if (m_exception) JSValueUnprotect(m_context, m_exception); JSGlobalContextRelease(m_context); @@ -86,6 +91,37 @@ QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate(); } +QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length) +{ + // Note that this private data will be deleted in the object finalize function. + QNativeFunctionData* data = new QNativeFunctionData(this, fun); + JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionClass, reinterpret_cast<void*>(data)); + QScriptValuePrivate* proto = prototype ? prototype : newObject(); + return newFunction(funJS, proto); +} + +QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg) +{ + // Note that this private data will be deleted in the object finalize function. + QNativeFunctionWithArgData* data = new QNativeFunctionWithArgData(this, fun, arg); + JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionWithArgClass, reinterpret_cast<void*>(data)); + QScriptValuePrivate* proto = newObject(); + return newFunction(funJS, proto); +} + +QScriptValuePrivate* QScriptEnginePrivate::newFunction(JSObjectRef funJS, QScriptValuePrivate* prototype) +{ + JSObjectSetPrototype(m_context, funJS, m_originalGlobalObject.functionPrototype()); + + QScriptValuePrivate* result = new QScriptValuePrivate(this, funJS); + static JSStringRef protoName = QScriptConverter::toString("prototype"); + static JSStringRef constructorName = QScriptConverter::toString("constructor"); + result->setProperty(protoName, prototype, QScriptValue::Undeletable); + prototype->setProperty(constructorName, result, QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + + return result; +} + QScriptValuePrivate* QScriptEnginePrivate::newObject() const { return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0)); diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h index d54cdcc..eec1929 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.h +++ b/JavaScriptCore/qt/api/qscriptengine_p.h @@ -71,6 +71,10 @@ public: inline JSValueRef makeJSValue(bool number) const; inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const; + QScriptValuePrivate* newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length); + QScriptValuePrivate* newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg); + QScriptValuePrivate* newFunction(JSObjectRef funObject, QScriptValuePrivate* prototype); + QScriptValuePrivate* newObject() const; QScriptValuePrivate* newArray(uint length); QScriptValuePrivate* globalObject() const; @@ -89,6 +93,9 @@ private: JSValueRef m_exception; QScriptOriginalGlobalObject m_originalGlobalObject; + + JSClassRef m_nativeFunctionClass; + JSClassRef m_nativeFunctionWithArgClass; }; diff --git a/JavaScriptCore/qt/api/qscriptfunction.cpp b/JavaScriptCore/qt/api/qscriptfunction.cpp new file mode 100644 index 0000000..9fe37e6 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptfunction.cpp @@ -0,0 +1,145 @@ +/* + 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. +*/ + +// Contains the necessary helper structures to make possible expose +// C/C++ functions to JavaScript environment. + +#include "config.h" + +#include "qscriptfunction_p.h" + +static void qt_NativeFunction_finalize(JSObjectRef object) +{ + void* priv = JSObjectGetPrivate(object); + delete reinterpret_cast<QNativeFunctionData*>(priv); +} + +static JSValueRef qt_NativeFunction_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + QNativeFunctionData* data = reinterpret_cast<QNativeFunctionData*>(JSObjectGetPrivate(object)); + + // TODO: build a QScriptContext and use it in the native call. + QScriptContext* scriptContext = 0; + Q_UNUSED(context); + Q_UNUSED(thisObject); + Q_UNUSED(argumentCount); + Q_UNUSED(arguments); + Q_UNUSED(exception); + + QScriptEnginePrivate* engine = data->engine; + QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine))); + if (!result->isValid()) { + qWarning("Invalid value returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + // Make sure that the result will be assigned to the correct engine. + if (!result->engine()) { + Q_ASSERT(result->isValid()); + result->assignEngine(engine); + } else if (result->engine() != engine) { + qWarning("Value from different engine returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + return *result; +} + +JSClassDefinition qt_NativeFunctionClass = { + 0, // version + kJSClassAttributeNoAutomaticPrototype, // attributes + + "", // className + 0, // parentClass + + 0, // staticValues + 0, // staticFunctions + + 0, // initialize + qt_NativeFunction_finalize, // finalize + 0, // hasProperty + 0, // getProperty + 0, // setProperty + 0, // deleteProperty + 0, // getPropertyNames + qt_NativeFunction_callAsFunction, // callAsFunction + 0, // callAsConstructor + 0, // hasInstance + 0 // convertToType +}; + +static void qt_NativeFunctionWithArg_finalize(JSObjectRef object) +{ + void* priv = JSObjectGetPrivate(object); + delete reinterpret_cast<QNativeFunctionWithArgData*>(priv); +} + +static JSValueRef qt_NativeFunctionWithArg_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + QNativeFunctionWithArgData* data = reinterpret_cast<QNativeFunctionWithArgData*>(JSObjectGetPrivate(object)); + + // TODO: build a QScriptContext and use it in the native call. + QScriptContext* scriptContext = 0; + Q_UNUSED(context); + Q_UNUSED(thisObject); + Q_UNUSED(argumentCount); + Q_UNUSED(arguments); + Q_UNUSED(exception); + + QScriptEnginePrivate* engine = data->engine; + QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine), data->arg)); + if (!result->isValid()) { + qWarning("Invalid value returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + // Make sure that the result will be assigned to the correct engine. + if (!result->engine()) { + Q_ASSERT(result->isValid()); + result->assignEngine(engine); + } else if (result->engine() != engine) { + qWarning("Value from different engine returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + return *result; +} + +JSClassDefinition qt_NativeFunctionWithArgClass = { + 0, // version + kJSClassAttributeNoAutomaticPrototype, // attributes + + "", // className + 0, // parentClass + + 0, // staticValues + 0, // staticFunctions + + 0, // initialize + qt_NativeFunctionWithArg_finalize, // finalize + 0, // hasProperty + 0, // getProperty + 0, // setProperty + 0, // deleteProperty + 0, // getPropertyNames + qt_NativeFunctionWithArg_callAsFunction, // callAsFunction + 0, // callAsConstructor + 0, // hasInstance + 0 // convertToType +}; diff --git a/JavaScriptCore/qt/api/qscriptfunction_p.h b/JavaScriptCore/qt/api/qscriptfunction_p.h new file mode 100644 index 0000000..65b6046 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptfunction_p.h @@ -0,0 +1,57 @@ +/* + 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. +*/ + +#ifndef qscriptfunction_p_h +#define qscriptfunction_p_h + +#include "config.h" + +#include "qscriptengine.h" +#include "qscriptvalue_p.h" + +extern JSClassDefinition qt_NativeFunctionClass; +extern JSClassDefinition qt_NativeFunctionWithArgClass; + +struct QNativeFunctionData +{ + QNativeFunctionData(QScriptEnginePrivate* engine, QScriptEngine::FunctionSignature fun) + : engine(engine) + , fun(fun) + { + } + + QScriptEnginePrivate* engine; + QScriptEngine::FunctionSignature fun; +}; + +struct QNativeFunctionWithArgData +{ + QNativeFunctionWithArgData(QScriptEnginePrivate* engine, QScriptEngine::FunctionWithArgSignature fun, void* arg) + : engine(engine) + , fun(fun) + , arg(arg) + { + } + + QScriptEnginePrivate* engine; + QScriptEngine::FunctionWithArgSignature fun; + void* arg; +}; + +#endif diff --git a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h index 8d080fb..31e94f7 100644 --- a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h +++ b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h @@ -45,6 +45,8 @@ public: inline bool isArray(JSValueRef value) const; inline bool isError(JSValueRef value) const; + + inline JSValueRef functionPrototype() const; private: inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const; inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype); @@ -57,6 +59,8 @@ private: JSValueRef m_arrayPrototype; JSObjectRef m_errorConstructor; JSValueRef m_errorPrototype; + JSObjectRef m_functionConstructor; + JSValueRef m_functionPrototype; // Reference to standard JS functions that are not exposed by JSC C API. JSObjectRef m_hasOwnPropertyFunction; @@ -73,6 +77,7 @@ QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef cont propertyName.adopt(JSStringCreateWithUTF8CString("prototype")); initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype); initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype); + initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype); propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty")); m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception)); @@ -119,6 +124,8 @@ QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject() JSValueUnprotect(m_context, m_arrayPrototype); JSValueUnprotect(m_context, m_errorConstructor); JSValueUnprotect(m_context, m_errorPrototype); + JSValueUnprotect(m_context, m_functionConstructor); + JSValueUnprotect(m_context, m_functionPrototype); JSValueUnprotect(m_context, m_hasOwnPropertyFunction); JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction); JSGlobalContextRelease(m_context); @@ -173,6 +180,11 @@ inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const return isType(value, m_errorConstructor, m_errorPrototype); } +inline JSValueRef QScriptOriginalGlobalObject::functionPrototype() const +{ + return m_functionPrototype; +} + inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const { // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h index 6e93a07..6fbf98b 100644 --- a/JavaScriptCore/qt/api/qscriptvalue_p.h +++ b/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -699,16 +699,48 @@ bool QScriptValuePrivate::equals(QScriptValuePrivate* other) if (!other->isValid()) return false; - if ((m_state == other->m_state) && !isJSBased()) { - if (isNumberBased()) - return u.m_number == other->u.m_number; - Q_ASSERT(isStringBased()); - return *u.m_string == *(other->u.m_string); + if (!isJSBased() && !other->isJSBased()) { + switch (m_state) { + case CNull: + case CUndefined: + return other->isUndefined() || other->isNull(); + case CNumber: + switch (other->m_state) { + case CBool: + case CString: + return u.m_number == other->toNumber(); + case CNumber: + return u.m_number == other->u.m_number; + default: + return false; + } + case CBool: + switch (other->m_state) { + case CBool: + return u.m_bool == other->u.m_bool; + case CNumber: + return toNumber() == other->u.m_number; + case CString: + return toNumber() == other->toNumber(); + default: + return false; + } + case CString: + switch (other->m_state) { + case CBool: + return toNumber() == other->toNumber(); + case CNumber: + return toNumber() == other->u.m_number; + case CString: + return *u.m_string == *other->u.m_string; + default: + return false; + } + default: + Q_ASSERT_X(false, "equals()", "Not all states are included in the previous switch statement."); + } } - if (!isJSBased() && !other->isJSBased()) - return false; - if (isJSBased() && !other->isJSBased()) { if (!other->assignEngine(engine())) { qWarning("equals(): Cannot compare to a value created in a different engine"); diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp index 72ca9b1..58a1587 100644 --- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp +++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp @@ -35,6 +35,7 @@ public slots: void cleanup() {} private slots: + void newFunction(); void newObject(); void globalObject(); void evaluate(); @@ -59,6 +60,146 @@ void tst_QScriptEngine::evaluate() QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value"); } +static QScriptValue myFunction(QScriptContext*, QScriptEngine* eng) +{ + return eng->nullValue(); +} + +static QScriptValue myFunctionWithArg(QScriptContext*, QScriptEngine* eng, void* arg) +{ + int* result = reinterpret_cast<int*>(arg); + return QScriptValue(eng, *result); +} + +static QScriptValue myFunctionThatReturns(QScriptContext*, QScriptEngine* eng) +{ + return QScriptValue(eng, 42); +} + +static QScriptValue myFunctionThatReturnsWithoutEngine(QScriptContext*, QScriptEngine*) +{ + return QScriptValue(1024); +} + +static QScriptValue myFunctionThatReturnsWrongEngine(QScriptContext*, QScriptEngine*, void* arg) +{ + QScriptEngine* wrongEngine = reinterpret_cast<QScriptEngine*>(arg); + return QScriptValue(wrongEngine, 42); +} + +void tst_QScriptEngine::newFunction() +{ + QScriptEngine eng; + { + QScriptValue fun = eng.newFunction(myFunction); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + // QCOMPARE(fun.scriptClass(), (QScriptClass*)0); + // a prototype property is automatically constructed + { + QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); + QVERIFY(prot.isObject()); + QVERIFY(prot.property("constructor").strictlyEquals(fun)); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + } + // prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + + QCOMPARE(fun.call().isNull(), true); + // QCOMPARE(fun.construct().isObject(), true); + } + // the overload that takes an extra argument + { + int expectedResult = 42; + QScriptValue fun = eng.newFunction(myFunctionWithArg, reinterpret_cast<void*>(&expectedResult)); + QVERIFY(fun.isFunction()); + // QCOMPARE(fun.scriptClass(), (QScriptClass*)0); + // a prototype property is automatically constructed + { + QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); + QVERIFY(prot.isObject()); + QVERIFY(prot.property("constructor").strictlyEquals(fun)); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + } + // prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), expectedResult); + } + // the overload that takes a prototype + { + QScriptValue proto = eng.newObject(); + QScriptValue fun = eng.newFunction(myFunction, proto); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + // internal prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + // public prototype should be the one we passed + QCOMPARE(fun.property("prototype").strictlyEquals(proto), true); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QCOMPARE(proto.property("constructor").strictlyEquals(fun), true); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + + QCOMPARE(fun.call().isNull(), true); + // QCOMPARE(fun.construct().isObject(), true); + } + // whether the return value is correct + { + QScriptValue fun = eng.newFunction(myFunctionThatReturns); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), 42); + } + // whether the return value is assigned to the correct engine + { + QScriptValue fun = eng.newFunction(myFunctionThatReturnsWithoutEngine); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.engine(), &eng); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), 1024); + } + // whether the return value is undefined when returning a value with wrong engine + { + QScriptEngine wrongEngine; + + QScriptValue fun = eng.newFunction(myFunctionThatReturnsWrongEngine, reinterpret_cast<void*>(&wrongEngine)); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QTest::ignoreMessage(QtWarningMsg, "Value from different engine returned from native function, returning undefined value instead."); + QScriptValue result = fun.call(); + QCOMPARE(result.isValid(), true); + QCOMPARE(result.isUndefined(), true); + } +} + void tst_QScriptEngine::newObject() { QScriptEngine engine; diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp index a82347e..e04d3e9 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp @@ -21,40 +21,15 @@ #include <QtCore/qnumeric.h> tst_QScriptValue::tst_QScriptValue() - : engine(0) + : m_engine(0) { } tst_QScriptValue::~tst_QScriptValue() { - delete engine; + delete m_engine; } -void tst_QScriptValue::dataHelper(InitDataFunction init, DefineDataFunction define) -{ - QTest::addColumn<QString>("__expression__"); - (this->*init)(); - QHash<QString, QScriptValue>::const_iterator it; - for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { - m_currentExpression = it.key(); - (this->*define)(it.key().toLatin1()); - } - m_currentExpression = QString(); -} - -QTestData& tst_QScriptValue::newRow(const char* tag) -{ - return QTest::newRow(tag) << m_currentExpression; -} - -void tst_QScriptValue::testHelper(TestFunction fun) -{ - QFETCH(QString, __expression__); - QScriptValue value = m_values.value(__expression__); - (this->*fun)(__expression__.toLatin1(), value); -} - - void tst_QScriptValue::ctor() { QScriptEngine eng; @@ -1285,4 +1260,37 @@ void tst_QScriptValue::globalObjectChanges() QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid()); } +void tst_QScriptValue::assignAndCopyConstruct_data() +{ + QTest::addColumn<QScriptValue>("value"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine; + // Copy & assign code is the same for all types, so it is enough to check only a few value. + for (unsigned i = 0; i < 10; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second; + } +} + +void tst_QScriptValue::assignAndCopyConstruct() +{ + QFETCH(QScriptValue, value); + QScriptValue copy(value); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Abort); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Abort); + QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber())); + QCOMPARE(copy.engine(), value.engine()); + + QScriptValue assigned = copy; + QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber())); + QCOMPARE(assigned.engine(), assigned.engine()); + + QScriptValue other(!value.toBool()); + assigned = other; + QVERIFY(!assigned.strictlyEquals(copy)); + QVERIFY(assigned.strictlyEquals(other)); + QCOMPARE(assigned.engine(), other.engine()); +} + QTEST_MAIN(tst_QScriptValue) diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h index 41b99cd..7b7d9bc 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h @@ -29,6 +29,8 @@ Q_DECLARE_METATYPE(QScriptValue*); Q_DECLARE_METATYPE(QScriptValue); +typedef QPair<QString, QScriptValue> QPairQStringAndQScriptValue; +Q_DECLARE_METATYPE(QPairQStringAndQScriptValue); class tst_QScriptValue : public QObject { Q_OBJECT @@ -61,14 +63,22 @@ private slots: void propertyFlag_data(); void propertyFlag(); void globalObjectChanges(); + void assignAndCopyConstruct_data(); + void assignAndCopyConstruct(); // Generated test functions. + void isArray_data(); + void isArray(); + void isBool_data(); void isBool(); void isBoolean_data(); void isBoolean(); + void isError_data(); + void isError(); + void isNumber_data(); void isNumber(); @@ -124,108 +134,10 @@ private slots: void instanceOf(); private: - typedef void (tst_QScriptValue::*InitDataFunction)(); - typedef void (tst_QScriptValue::*DefineDataFunction)(const char*); - void dataHelper(InitDataFunction init, DefineDataFunction define); - QTestData& newRow(const char* tag); - - typedef void (tst_QScriptValue::*TestFunction)(const char*, const QScriptValue&); - void testHelper(TestFunction fun); - - // Generated functions - - void initScriptValues(); - - void isBool_initData(); - void isBool_makeData(const char* expr); - void isBool_test(const char* expr, const QScriptValue& value); - - void isBoolean_initData(); - void isBoolean_makeData(const char* expr); - void isBoolean_test(const char* expr, const QScriptValue& value); - - void isNumber_initData(); - void isNumber_makeData(const char* expr); - void isNumber_test(const char* expr, const QScriptValue&); - - void isFunction_initData(); - void isFunction_makeData(const char* expr); - void isFunction_test(const char* expr, const QScriptValue& value); - - void isNull_initData(); - void isNull_makeData(const char* expr); - void isNull_test(const char* expr, const QScriptValue& value); - - void isObject_initData(); - void isObject_makeData(const char* expr); - void isObject_test(const char* expr, const QScriptValue& value); - - void isString_initData(); - void isString_makeData(const char* expr); - void isString_test(const char* expr, const QScriptValue& value); - - void isUndefined_initData(); - void isUndefined_makeData(const char* expr); - void isUndefined_test(const char* expr, const QScriptValue& value); - - void isValid_initData(); - void isValid_makeData(const char* expr); - void isValid_test(const char* expr, const QScriptValue& value); - - void toString_initData(); - void toString_makeData(const char*); - void toString_test(const char*, const QScriptValue&); + // Generated function + QPair<QString, QScriptValue> initScriptValues(uint idx); - void toNumber_initData(); - void toNumber_makeData(const char*); - void toNumber_test(const char*, const QScriptValue&); - - void toBool_initData(); - void toBool_makeData(const char*); - void toBool_test(const char*, const QScriptValue&); - - void toBoolean_initData(); - void toBoolean_makeData(const char*); - void toBoolean_test(const char*, const QScriptValue&); - - void toInteger_initData(); - void toInteger_makeData(const char*); - void toInteger_test(const char*, const QScriptValue&); - - void toInt32_initData(); - void toInt32_makeData(const char*); - void toInt32_test(const char*, const QScriptValue&); - - void toUInt32_initData(); - void toUInt32_makeData(const char*); - void toUInt32_test(const char*, const QScriptValue&); - - void toUInt16_initData(); - void toUInt16_makeData(const char*); - void toUInt16_test(const char*, const QScriptValue&); - - void equals_initData(); - void equals_makeData(const char*); - void equals_test(const char*, const QScriptValue&); - - void strictlyEquals_initData(); - void strictlyEquals_makeData(const char*); - void strictlyEquals_test(const char*, const QScriptValue&); - - void instanceOf_initData(); - void instanceOf_makeData(const char*); - void instanceOf_test(const char*, const QScriptValue&); - -private: - QScriptEngine* engine; - QHash<QString, QScriptValue> m_values; - QString m_currentExpression; + QScriptEngine* m_engine; }; -#define DEFINE_TEST_FUNCTION(name) \ -void tst_QScriptValue::name##_data() { dataHelper(&tst_QScriptValue::name##_initData, &tst_QScriptValue::name##_makeData); } \ -void tst_QScriptValue::name() { testHelper(&tst_QScriptValue::name##_test); } - - - #endif // tst_qscriptvalue_h diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp index 7586b15..3209530 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp @@ -23,14 +23,7 @@ #include "tst_qscriptvalue.h" -void tst_QScriptValue::equals_initData() -{ - QTest::addColumn<QScriptValue>("other"); - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString equals_array[] = { +static const QString equals_array[] = { "QScriptValue() <=> QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::NullValue)", @@ -84,6 +77,7 @@ static QString equals_array[] = { "QScriptValue(false) <=> engine->evaluate(\"0.0\")", "QScriptValue(false) <=> engine->evaluate(\"''\")", "QScriptValue(false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(false) <=> engine->newArray()", "QScriptValue(int(122)) <=> QScriptValue(int(122))", "QScriptValue(int(122)) <=> QScriptValue(0, int(122))", "QScriptValue(int(122)) <=> QScriptValue(engine, int(122))", @@ -118,6 +112,7 @@ static QString equals_array[] = { "QScriptValue(0) <=> engine->evaluate(\"0.0\")", "QScriptValue(0) <=> engine->evaluate(\"''\")", "QScriptValue(0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0) <=> engine->newArray()", "QScriptValue(0.0) <=> QScriptValue(false)", "QScriptValue(0.0) <=> QScriptValue(0)", "QScriptValue(0.0) <=> QScriptValue(0.0)", @@ -144,6 +139,7 @@ static QString equals_array[] = { "QScriptValue(0.0) <=> engine->evaluate(\"0.0\")", "QScriptValue(0.0) <=> engine->evaluate(\"''\")", "QScriptValue(0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0.0) <=> engine->newArray()", "QScriptValue(123.0) <=> QScriptValue(123.0)", "QScriptValue(123.0) <=> QScriptValue(QString(\"123\"))", "QScriptValue(123.0) <=> QScriptValue(0, 123.0)", @@ -239,6 +235,7 @@ static QString equals_array[] = { "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0.0\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(QString(\"\")) <=> engine->newArray()", "QScriptValue(QString()) <=> QScriptValue(false)", "QScriptValue(QString()) <=> QScriptValue(0)", "QScriptValue(QString()) <=> QScriptValue(0.0)", @@ -261,6 +258,7 @@ static QString equals_array[] = { "QScriptValue(QString()) <=> engine->evaluate(\"0\")", "QScriptValue(QString()) <=> engine->evaluate(\"0.0\")", "QScriptValue(QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(QString()) <=> engine->newArray()", "QScriptValue(QString(\"0\")) <=> QScriptValue(false)", "QScriptValue(QString(\"0\")) <=> QScriptValue(0)", "QScriptValue(QString(\"0\")) <=> QScriptValue(0.0)", @@ -339,6 +337,7 @@ static QString equals_array[] = { "QScriptValue(0, false) <=> engine->evaluate(\"0.0\")", "QScriptValue(0, false) <=> engine->evaluate(\"''\")", "QScriptValue(0, false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, false) <=> engine->newArray()", "QScriptValue(0, int(122)) <=> QScriptValue(int(122))", "QScriptValue(0, int(122)) <=> QScriptValue(0, int(122))", "QScriptValue(0, int(122)) <=> QScriptValue(engine, int(122))", @@ -373,6 +372,7 @@ static QString equals_array[] = { "QScriptValue(0, 0) <=> engine->evaluate(\"0.0\")", "QScriptValue(0, 0) <=> engine->evaluate(\"''\")", "QScriptValue(0, 0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, 0) <=> engine->newArray()", "QScriptValue(0, 0.0) <=> QScriptValue(false)", "QScriptValue(0, 0.0) <=> QScriptValue(0)", "QScriptValue(0, 0.0) <=> QScriptValue(0.0)", @@ -399,6 +399,7 @@ static QString equals_array[] = { "QScriptValue(0, 0.0) <=> engine->evaluate(\"0.0\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"''\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, 0.0) <=> engine->newArray()", "QScriptValue(0, 123.0) <=> QScriptValue(123.0)", "QScriptValue(0, 123.0) <=> QScriptValue(QString(\"123\"))", "QScriptValue(0, 123.0) <=> QScriptValue(0, 123.0)", @@ -494,6 +495,7 @@ static QString equals_array[] = { "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0.0\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString(\"\")) <=> engine->newArray()", "QScriptValue(0, QString()) <=> QScriptValue(false)", "QScriptValue(0, QString()) <=> QScriptValue(0)", "QScriptValue(0, QString()) <=> QScriptValue(0.0)", @@ -516,6 +518,7 @@ static QString equals_array[] = { "QScriptValue(0, QString()) <=> engine->evaluate(\"0\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"0.0\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString()) <=> engine->newArray()", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(false)", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0)", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0.0)", @@ -593,6 +596,7 @@ static QString equals_array[] = { "QScriptValue(engine, false) <=> engine->evaluate(\"0.0\")", "QScriptValue(engine, false) <=> engine->evaluate(\"''\")", "QScriptValue(engine, false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, false) <=> engine->newArray()", "QScriptValue(engine, int(122)) <=> QScriptValue(int(122))", "QScriptValue(engine, int(122)) <=> QScriptValue(0, int(122))", "QScriptValue(engine, int(122)) <=> QScriptValue(engine, int(122))", @@ -627,6 +631,7 @@ static QString equals_array[] = { "QScriptValue(engine, 0) <=> engine->evaluate(\"0.0\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"''\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, 0) <=> engine->newArray()", "QScriptValue(engine, 0.0) <=> QScriptValue(false)", "QScriptValue(engine, 0.0) <=> QScriptValue(0)", "QScriptValue(engine, 0.0) <=> QScriptValue(0.0)", @@ -653,6 +658,7 @@ static QString equals_array[] = { "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0.0\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"''\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, 0.0) <=> engine->newArray()", "QScriptValue(engine, 123.0) <=> QScriptValue(123.0)", "QScriptValue(engine, 123.0) <=> QScriptValue(QString(\"123\"))", "QScriptValue(engine, 123.0) <=> QScriptValue(0, 123.0)", @@ -748,6 +754,7 @@ static QString equals_array[] = { "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0.0\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString(\"\")) <=> engine->newArray()", "QScriptValue(engine, QString()) <=> QScriptValue(false)", "QScriptValue(engine, QString()) <=> QScriptValue(0)", "QScriptValue(engine, QString()) <=> QScriptValue(0.0)", @@ -770,6 +777,7 @@ static QString equals_array[] = { "QScriptValue(engine, QString()) <=> engine->evaluate(\"0\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"0.0\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString()) <=> engine->newArray()", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(false)", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0)", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0.0)", @@ -810,7 +818,6 @@ static QString equals_array[] = { "engine->evaluate(\"[]\") <=> QScriptValue(engine, 0.0)", "engine->evaluate(\"[]\") <=> QScriptValue(engine, QString(\"\"))", "engine->evaluate(\"[]\") <=> QScriptValue(engine, QString())", - "engine->evaluate(\"[]\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"0.0\")", @@ -854,11 +861,6 @@ static QString equals_array[] = { "engine->evaluate(\"Array\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"Number\") <=> engine->evaluate(\"Number\")", "engine->evaluate(\"Function\") <=> engine->evaluate(\"Function\")", - "engine->evaluate(\"(function() { return 1; })\") <=> engine->evaluate(\"(function() { return 1; })\")", - "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\") <=> engine->evaluate(\"(function() { throw new Error('foo' })\")", - "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"/foo/\")", - "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\") <=> QScriptValue(false)", "engine->evaluate(\"new Array()\") <=> QScriptValue(0)", "engine->evaluate(\"new Array()\") <=> QScriptValue(0.0)", @@ -874,17 +876,11 @@ static QString equals_array[] = { "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, 0.0)", "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString(\"\"))", "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString())", - "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"''\")", - "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", - "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Undefined\")", - "engine->evaluate(\"Null\") <=> engine->evaluate(\"Null\")", - "engine->evaluate(\"True\") <=> engine->evaluate(\"True\")", - "engine->evaluate(\"False\") <=> engine->evaluate(\"False\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::UndefinedValue)", "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::NullValue)", "engine->evaluate(\"undefined\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", @@ -937,6 +933,7 @@ static QString equals_array[] = { "engine->evaluate(\"false\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"''\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"false\") <=> engine->newArray()", "engine->evaluate(\"122\") <=> QScriptValue(int(122))", "engine->evaluate(\"122\") <=> QScriptValue(0, int(122))", "engine->evaluate(\"122\") <=> QScriptValue(engine, int(122))", @@ -971,6 +968,7 @@ static QString equals_array[] = { "engine->evaluate(\"0\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"''\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"0\") <=> engine->newArray()", "engine->evaluate(\"0.0\") <=> QScriptValue(false)", "engine->evaluate(\"0.0\") <=> QScriptValue(0)", "engine->evaluate(\"0.0\") <=> QScriptValue(0.0)", @@ -997,6 +995,7 @@ static QString equals_array[] = { "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"''\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"0.0\") <=> engine->newArray()", "engine->evaluate(\"123.0\") <=> QScriptValue(123.0)", "engine->evaluate(\"123.0\") <=> QScriptValue(QString(\"123\"))", "engine->evaluate(\"123.0\") <=> QScriptValue(0, 123.0)", @@ -1068,6 +1067,7 @@ static QString equals_array[] = { "engine->evaluate(\"''\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"''\") <=> engine->newArray()", "engine->evaluate(\"'0'\") <=> QScriptValue(false)", "engine->evaluate(\"'0'\") <=> QScriptValue(0)", "engine->evaluate(\"'0'\") <=> QScriptValue(0.0)", @@ -1115,41 +1115,73 @@ static QString equals_array[] = { "engine->undefinedValue() <=> engine->evaluate(\"undefined\")", "engine->undefinedValue() <=> engine->evaluate(\"null\")", "engine->undefinedValue() <=> engine->nullValue()", - "engine->undefinedValue() <=> engine->undefinedValue()"}; + "engine->undefinedValue() <=> engine->undefinedValue()", + "engine->newArray() <=> QScriptValue(false)", + "engine->newArray() <=> QScriptValue(0)", + "engine->newArray() <=> QScriptValue(0.0)", + "engine->newArray() <=> QScriptValue(QString(\"\"))", + "engine->newArray() <=> QScriptValue(QString())", + "engine->newArray() <=> QScriptValue(0, false)", + "engine->newArray() <=> QScriptValue(0, 0)", + "engine->newArray() <=> QScriptValue(0, 0.0)", + "engine->newArray() <=> QScriptValue(0, QString(\"\"))", + "engine->newArray() <=> QScriptValue(0, QString())", + "engine->newArray() <=> QScriptValue(engine, false)", + "engine->newArray() <=> QScriptValue(engine, 0)", + "engine->newArray() <=> QScriptValue(engine, 0.0)", + "engine->newArray() <=> QScriptValue(engine, QString(\"\"))", + "engine->newArray() <=> QScriptValue(engine, QString())", + "engine->newArray() <=> engine->evaluate(\"false\")", + "engine->newArray() <=> engine->evaluate(\"0\")", + "engine->newArray() <=> engine->evaluate(\"0.0\")", + "engine->newArray() <=> engine->evaluate(\"''\")"}; -void tst_QScriptValue::equals_makeData(const char *expr) +void tst_QScriptValue::equals_data() { - static QSet<QString> equals; - if (equals.isEmpty()) { - equals.reserve(1085); - for (unsigned i = 0; i < 1085; ++i) - equals.insert(equals_array[i]); - } - QHash<QString, QScriptValue>::const_iterator it; - for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { - QString tag = QString::fromLatin1("%20 <=> %21").arg(expr).arg(it.key()); - newRow(tag.toLatin1()) << it.value() << equals.contains(tag); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(1111); + for (unsigned i = 0; i < 1111; ++i) + equals.insert(equals_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } } } -void tst_QScriptValue::equals_test(const char *, const QScriptValue& value) +void tst_QScriptValue::equals() { + QFETCH(QScriptValue, value); QFETCH(QScriptValue, other); QFETCH(bool, expected); + QEXPECT_FAIL("QScriptValue(qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(-qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(-qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(-qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(0, qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(0, -qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, -qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, -qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(-qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, -qInf())", "FIXME: WebKit bug 43038", Continue); QCOMPARE(value.equals(other), expected); } -DEFINE_TEST_FUNCTION(equals) - - -void tst_QScriptValue::strictlyEquals_initData() -{ - QTest::addColumn<QScriptValue>("other"); - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString strictlyEquals_array[] = { +static const QString strictlyEquals_array[] = { "QScriptValue() <=> QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", @@ -1515,7 +1547,6 @@ static QString strictlyEquals_array[] = { "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"'123'\")", "QScriptValue(engine, QString(\"1.23\")) <=> QScriptValue(engine, QString(\"1.23\"))", - "engine->evaluate(\"[]\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"{}\") <=> QScriptValue(QScriptValue::UndefinedValue)", "engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", "engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", @@ -1531,18 +1562,7 @@ static QString strictlyEquals_array[] = { "engine->evaluate(\"Array\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"Number\") <=> engine->evaluate(\"Number\")", "engine->evaluate(\"Function\") <=> engine->evaluate(\"Function\")", - "engine->evaluate(\"(function() { return 1; })\") <=> engine->evaluate(\"(function() { return 1; })\")", - "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\") <=> engine->evaluate(\"(function() { throw new Error('foo' })\")", - "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"/foo/\")", - "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new Object()\")", - "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")", - "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", - "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Undefined\")", - "engine->evaluate(\"Null\") <=> engine->evaluate(\"Null\")", - "engine->evaluate(\"True\") <=> engine->evaluate(\"True\")", - "engine->evaluate(\"False\") <=> engine->evaluate(\"False\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::UndefinedValue)", "engine->evaluate(\"undefined\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", "engine->evaluate(\"undefined\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", @@ -1654,39 +1674,66 @@ static QString strictlyEquals_array[] = { "engine->undefinedValue() <=> engine->evaluate(\"undefined\")", "engine->undefinedValue() <=> engine->undefinedValue()"}; -void tst_QScriptValue::strictlyEquals_makeData(const char* expr) +void tst_QScriptValue::strictlyEquals_data() { - static QSet<QString> equals; - if (equals.isEmpty()) { - equals.reserve(503); - for (unsigned i = 0; i < 503; ++i) - equals.insert(strictlyEquals_array[i]); - } - QHash<QString, QScriptValue>::const_iterator it; - for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { - QString tag = QString::fromLatin1("%20 <=> %21").arg(expr).arg(it.key()); - newRow(tag.toLatin1()) << it.value() << equals.contains(tag); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(491); + for (unsigned i = 0; i < 491; ++i) + equals.insert(strictlyEquals_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } } } -void tst_QScriptValue::strictlyEquals_test(const char*, const QScriptValue& value) +void tst_QScriptValue::strictlyEquals() { + QFETCH(QScriptValue, value); QFETCH(QScriptValue, other); QFETCH(bool, expected); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"null\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(true) <=> QScriptValue(true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(true) <=> QScriptValue(0, true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(false) <=> QScriptValue(false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(false) <=> QScriptValue(0, false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, true) <=> QScriptValue(true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, true) <=> QScriptValue(0, true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, false) <=> QScriptValue(false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, false) <=> QScriptValue(0, false)", "FIXME: WebKit bug 43038", Continue); QCOMPARE(value.strictlyEquals(other), expected); } -DEFINE_TEST_FUNCTION(strictlyEquals) - - -void tst_QScriptValue::instanceOf_initData() -{ - QTest::addColumn<QScriptValue>("other"); - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString instanceOf_array[] = { +static const QString instanceOf_array[] = { "engine->evaluate(\"[]\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Object\")", @@ -1705,38 +1752,48 @@ static QString instanceOf_array[] = { "engine->evaluate(\"(function() { return 1; })\") <=> engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"Function\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\") <=> engine->evaluate(\"Function\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"Object\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"Object\")", - "engine->evaluate(\"False\") <=> engine->evaluate(\"Object\")"}; + "engine->evaluate(\"False\") <=> engine->evaluate(\"Object\")", + "engine->newObject() <=> engine->evaluate(\"Object\")", + "engine->newArray() <=> engine->evaluate(\"Object\")", + "engine->newArray() <=> engine->evaluate(\"Array\")", + "engine->newArray(10) <=> engine->evaluate(\"Object\")", + "engine->newArray(10) <=> engine->evaluate(\"Array\")"}; -void tst_QScriptValue::instanceOf_makeData(const char *expr) +void tst_QScriptValue::instanceOf_data() { - static QSet<QString> equals; - if (equals.isEmpty()) { - equals.reserve(29); - for (unsigned i = 0; i < 29; ++i) - equals.insert(instanceOf_array[i]); - } - QHash<QString, QScriptValue>::const_iterator it; - for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { - QString tag = QString::fromLatin1("%20 <=> %21").arg(expr).arg(it.key()); - newRow(tag.toLatin1()) << it.value() << equals.contains(tag); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(34); + for (unsigned i = 0; i < 34; ++i) + equals.insert(instanceOf_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } } } -void tst_QScriptValue::instanceOf_test(const char *, const QScriptValue& value) +void tst_QScriptValue::instanceOf() { + QFETCH(QScriptValue, value); QFETCH(QScriptValue, other); QFETCH(bool, expected); QCOMPARE(value.instanceOf(other), expected); } - -DEFINE_TEST_FUNCTION(instanceOf) diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp index b68aaf2..4c97dd4 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp @@ -24,142 +24,146 @@ #include "tst_qscriptvalue.h" -void tst_QScriptValue::initScriptValues() +QPair<QString, QScriptValue> tst_QScriptValue::initScriptValues(uint idx) { - m_values.clear(); - if (engine) - delete engine; - engine = new QScriptEngine; - DEFINE_TEST_VALUE(QScriptValue()); - DEFINE_TEST_VALUE(QScriptValue(QScriptValue::UndefinedValue)); - DEFINE_TEST_VALUE(QScriptValue(QScriptValue::NullValue)); - DEFINE_TEST_VALUE(QScriptValue(true)); - DEFINE_TEST_VALUE(QScriptValue(false)); - DEFINE_TEST_VALUE(QScriptValue(int(122))); - DEFINE_TEST_VALUE(QScriptValue(uint(124))); - DEFINE_TEST_VALUE(QScriptValue(0)); - DEFINE_TEST_VALUE(QScriptValue(0.0)); - DEFINE_TEST_VALUE(QScriptValue(123.0)); - DEFINE_TEST_VALUE(QScriptValue(6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(-6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(0x43211234)); - DEFINE_TEST_VALUE(QScriptValue(0x10000)); - DEFINE_TEST_VALUE(QScriptValue(0x10001)); - DEFINE_TEST_VALUE(QScriptValue(qSNaN())); - DEFINE_TEST_VALUE(QScriptValue(qQNaN())); - DEFINE_TEST_VALUE(QScriptValue(qInf())); - DEFINE_TEST_VALUE(QScriptValue(-qInf())); - DEFINE_TEST_VALUE(QScriptValue("NaN")); - DEFINE_TEST_VALUE(QScriptValue("Infinity")); - DEFINE_TEST_VALUE(QScriptValue("-Infinity")); - DEFINE_TEST_VALUE(QScriptValue("ciao")); - DEFINE_TEST_VALUE(QScriptValue(QString::fromLatin1("ciao"))); - DEFINE_TEST_VALUE(QScriptValue(QString(""))); - DEFINE_TEST_VALUE(QScriptValue(QString())); - DEFINE_TEST_VALUE(QScriptValue(QString("0"))); - DEFINE_TEST_VALUE(QScriptValue(QString("123"))); - DEFINE_TEST_VALUE(QScriptValue(QString("12.4"))); - DEFINE_TEST_VALUE(QScriptValue(0, QScriptValue::UndefinedValue)); - DEFINE_TEST_VALUE(QScriptValue(0, QScriptValue::NullValue)); - DEFINE_TEST_VALUE(QScriptValue(0, true)); - DEFINE_TEST_VALUE(QScriptValue(0, false)); - DEFINE_TEST_VALUE(QScriptValue(0, int(122))); - DEFINE_TEST_VALUE(QScriptValue(0, uint(124))); - DEFINE_TEST_VALUE(QScriptValue(0, 0)); - DEFINE_TEST_VALUE(QScriptValue(0, 0.0)); - DEFINE_TEST_VALUE(QScriptValue(0, 123.0)); - DEFINE_TEST_VALUE(QScriptValue(0, 6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(0, -6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(0, 0x43211234)); - DEFINE_TEST_VALUE(QScriptValue(0, 0x10000)); - DEFINE_TEST_VALUE(QScriptValue(0, 0x10001)); - DEFINE_TEST_VALUE(QScriptValue(0, qSNaN())); - DEFINE_TEST_VALUE(QScriptValue(0, qQNaN())); - DEFINE_TEST_VALUE(QScriptValue(0, qInf())); - DEFINE_TEST_VALUE(QScriptValue(0, -qInf())); - DEFINE_TEST_VALUE(QScriptValue(0, "NaN")); - DEFINE_TEST_VALUE(QScriptValue(0, "Infinity")); - DEFINE_TEST_VALUE(QScriptValue(0, "-Infinity")); - DEFINE_TEST_VALUE(QScriptValue(0, "ciao")); - DEFINE_TEST_VALUE(QScriptValue(0, QString::fromLatin1("ciao"))); - DEFINE_TEST_VALUE(QScriptValue(0, QString(""))); - DEFINE_TEST_VALUE(QScriptValue(0, QString())); - DEFINE_TEST_VALUE(QScriptValue(0, QString("0"))); - DEFINE_TEST_VALUE(QScriptValue(0, QString("123"))); - DEFINE_TEST_VALUE(QScriptValue(0, QString("12.3"))); - DEFINE_TEST_VALUE(QScriptValue(engine, QScriptValue::UndefinedValue)); - DEFINE_TEST_VALUE(QScriptValue(engine, QScriptValue::NullValue)); - DEFINE_TEST_VALUE(QScriptValue(engine, true)); - DEFINE_TEST_VALUE(QScriptValue(engine, false)); - DEFINE_TEST_VALUE(QScriptValue(engine, int(122))); - DEFINE_TEST_VALUE(QScriptValue(engine, uint(124))); - DEFINE_TEST_VALUE(QScriptValue(engine, 0)); - DEFINE_TEST_VALUE(QScriptValue(engine, 0.0)); - DEFINE_TEST_VALUE(QScriptValue(engine, 123.0)); - DEFINE_TEST_VALUE(QScriptValue(engine, 6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(engine, -6.37e-8)); - DEFINE_TEST_VALUE(QScriptValue(engine, 0x43211234)); - DEFINE_TEST_VALUE(QScriptValue(engine, 0x10000)); - DEFINE_TEST_VALUE(QScriptValue(engine, 0x10001)); - DEFINE_TEST_VALUE(QScriptValue(engine, qSNaN())); - DEFINE_TEST_VALUE(QScriptValue(engine, qQNaN())); - DEFINE_TEST_VALUE(QScriptValue(engine, qInf())); - DEFINE_TEST_VALUE(QScriptValue(engine, -qInf())); - DEFINE_TEST_VALUE(QScriptValue(engine, "NaN")); - DEFINE_TEST_VALUE(QScriptValue(engine, "Infinity")); - DEFINE_TEST_VALUE(QScriptValue(engine, "-Infinity")); - DEFINE_TEST_VALUE(QScriptValue(engine, "ciao")); - DEFINE_TEST_VALUE(QScriptValue(engine, QString::fromLatin1("ciao"))); - DEFINE_TEST_VALUE(QScriptValue(engine, QString(""))); - DEFINE_TEST_VALUE(QScriptValue(engine, QString())); - DEFINE_TEST_VALUE(QScriptValue(engine, QString("0"))); - DEFINE_TEST_VALUE(QScriptValue(engine, QString("123"))); - DEFINE_TEST_VALUE(QScriptValue(engine, QString("1.23"))); - DEFINE_TEST_VALUE(engine->evaluate("[]")); - DEFINE_TEST_VALUE(engine->evaluate("{}")); - DEFINE_TEST_VALUE(engine->evaluate("Object.prototype")); - DEFINE_TEST_VALUE(engine->evaluate("Date.prototype")); - DEFINE_TEST_VALUE(engine->evaluate("Array.prototype")); - DEFINE_TEST_VALUE(engine->evaluate("Function.prototype")); - DEFINE_TEST_VALUE(engine->evaluate("Error.prototype")); - DEFINE_TEST_VALUE(engine->evaluate("Object")); - DEFINE_TEST_VALUE(engine->evaluate("Array")); - DEFINE_TEST_VALUE(engine->evaluate("Number")); - DEFINE_TEST_VALUE(engine->evaluate("Function")); - DEFINE_TEST_VALUE(engine->evaluate("(function() { return 1; })")); - DEFINE_TEST_VALUE(engine->evaluate("(function() { return 'ciao'; })")); - DEFINE_TEST_VALUE(engine->evaluate("(function() { throw new Error('foo' })")); - DEFINE_TEST_VALUE(engine->evaluate("/foo/")); - DEFINE_TEST_VALUE(engine->evaluate("new Object()")); - DEFINE_TEST_VALUE(engine->evaluate("new Array()")); - DEFINE_TEST_VALUE(engine->evaluate("new Error()")); - DEFINE_TEST_VALUE(engine->evaluate("a = new Object( a.foo = 22; a.foo")); - DEFINE_TEST_VALUE(engine->evaluate("Undefined")); - DEFINE_TEST_VALUE(engine->evaluate("Null")); - DEFINE_TEST_VALUE(engine->evaluate("True")); - DEFINE_TEST_VALUE(engine->evaluate("False")); - DEFINE_TEST_VALUE(engine->evaluate("undefined")); - DEFINE_TEST_VALUE(engine->evaluate("null")); - DEFINE_TEST_VALUE(engine->evaluate("true")); - DEFINE_TEST_VALUE(engine->evaluate("false")); - DEFINE_TEST_VALUE(engine->evaluate("122")); - DEFINE_TEST_VALUE(engine->evaluate("124")); - DEFINE_TEST_VALUE(engine->evaluate("0")); - DEFINE_TEST_VALUE(engine->evaluate("0.0")); - DEFINE_TEST_VALUE(engine->evaluate("123.0")); - DEFINE_TEST_VALUE(engine->evaluate("6.37e-8")); - DEFINE_TEST_VALUE(engine->evaluate("-6.37e-8")); - DEFINE_TEST_VALUE(engine->evaluate("0x43211234")); - DEFINE_TEST_VALUE(engine->evaluate("0x10000")); - DEFINE_TEST_VALUE(engine->evaluate("0x10001")); - DEFINE_TEST_VALUE(engine->evaluate("NaN")); - DEFINE_TEST_VALUE(engine->evaluate("Infinity")); - DEFINE_TEST_VALUE(engine->evaluate("-Infinity")); - DEFINE_TEST_VALUE(engine->evaluate("'ciao'")); - DEFINE_TEST_VALUE(engine->evaluate("''")); - DEFINE_TEST_VALUE(engine->evaluate("'0'")); - DEFINE_TEST_VALUE(engine->evaluate("'123'")); - DEFINE_TEST_VALUE(engine->evaluate("'12.4'")); - DEFINE_TEST_VALUE(engine->nullValue()); - DEFINE_TEST_VALUE(engine->undefinedValue()); + QScriptEngine* engine = m_engine; + switch (idx) { + case 0: return QPair<QString, QScriptValue>("QScriptValue()", QScriptValue()); + case 1: return QPair<QString, QScriptValue>("QScriptValue(QScriptValue::UndefinedValue)", QScriptValue(QScriptValue::UndefinedValue)); + case 2: return QPair<QString, QScriptValue>("QScriptValue(QScriptValue::NullValue)", QScriptValue(QScriptValue::NullValue)); + case 3: return QPair<QString, QScriptValue>("QScriptValue(true)", QScriptValue(true)); + case 4: return QPair<QString, QScriptValue>("QScriptValue(false)", QScriptValue(false)); + case 5: return QPair<QString, QScriptValue>("QScriptValue(int(122))", QScriptValue(int(122))); + case 6: return QPair<QString, QScriptValue>("QScriptValue(uint(124))", QScriptValue(uint(124))); + case 7: return QPair<QString, QScriptValue>("QScriptValue(0)", QScriptValue(0)); + case 8: return QPair<QString, QScriptValue>("QScriptValue(0.0)", QScriptValue(0.0)); + case 9: return QPair<QString, QScriptValue>("QScriptValue(123.0)", QScriptValue(123.0)); + case 10: return QPair<QString, QScriptValue>("QScriptValue(6.37e-8)", QScriptValue(6.37e-8)); + case 11: return QPair<QString, QScriptValue>("QScriptValue(-6.37e-8)", QScriptValue(-6.37e-8)); + case 12: return QPair<QString, QScriptValue>("QScriptValue(0x43211234)", QScriptValue(0x43211234)); + case 13: return QPair<QString, QScriptValue>("QScriptValue(0x10000)", QScriptValue(0x10000)); + case 14: return QPair<QString, QScriptValue>("QScriptValue(0x10001)", QScriptValue(0x10001)); + case 15: return QPair<QString, QScriptValue>("QScriptValue(qSNaN())", QScriptValue(qSNaN())); + case 16: return QPair<QString, QScriptValue>("QScriptValue(qQNaN())", QScriptValue(qQNaN())); + case 17: return QPair<QString, QScriptValue>("QScriptValue(qInf())", QScriptValue(qInf())); + case 18: return QPair<QString, QScriptValue>("QScriptValue(-qInf())", QScriptValue(-qInf())); + case 19: return QPair<QString, QScriptValue>("QScriptValue(\"NaN\")", QScriptValue("NaN")); + case 20: return QPair<QString, QScriptValue>("QScriptValue(\"Infinity\")", QScriptValue("Infinity")); + case 21: return QPair<QString, QScriptValue>("QScriptValue(\"-Infinity\")", QScriptValue("-Infinity")); + case 22: return QPair<QString, QScriptValue>("QScriptValue(\"ciao\")", QScriptValue("ciao")); + case 23: return QPair<QString, QScriptValue>("QScriptValue(QString::fromLatin1(\"ciao\"))", QScriptValue(QString::fromLatin1("ciao"))); + case 24: return QPair<QString, QScriptValue>("QScriptValue(QString(\"\"))", QScriptValue(QString(""))); + case 25: return QPair<QString, QScriptValue>("QScriptValue(QString())", QScriptValue(QString())); + case 26: return QPair<QString, QScriptValue>("QScriptValue(QString(\"0\"))", QScriptValue(QString("0"))); + case 27: return QPair<QString, QScriptValue>("QScriptValue(QString(\"123\"))", QScriptValue(QString("123"))); + case 28: return QPair<QString, QScriptValue>("QScriptValue(QString(\"12.4\"))", QScriptValue(QString("12.4"))); + case 29: return QPair<QString, QScriptValue>("QScriptValue(0, QScriptValue::UndefinedValue)", QScriptValue(0, QScriptValue::UndefinedValue)); + case 30: return QPair<QString, QScriptValue>("QScriptValue(0, QScriptValue::NullValue)", QScriptValue(0, QScriptValue::NullValue)); + case 31: return QPair<QString, QScriptValue>("QScriptValue(0, true)", QScriptValue(0, true)); + case 32: return QPair<QString, QScriptValue>("QScriptValue(0, false)", QScriptValue(0, false)); + case 33: return QPair<QString, QScriptValue>("QScriptValue(0, int(122))", QScriptValue(0, int(122))); + case 34: return QPair<QString, QScriptValue>("QScriptValue(0, uint(124))", QScriptValue(0, uint(124))); + case 35: return QPair<QString, QScriptValue>("QScriptValue(0, 0)", QScriptValue(0, 0)); + case 36: return QPair<QString, QScriptValue>("QScriptValue(0, 0.0)", QScriptValue(0, 0.0)); + case 37: return QPair<QString, QScriptValue>("QScriptValue(0, 123.0)", QScriptValue(0, 123.0)); + case 38: return QPair<QString, QScriptValue>("QScriptValue(0, 6.37e-8)", QScriptValue(0, 6.37e-8)); + case 39: return QPair<QString, QScriptValue>("QScriptValue(0, -6.37e-8)", QScriptValue(0, -6.37e-8)); + case 40: return QPair<QString, QScriptValue>("QScriptValue(0, 0x43211234)", QScriptValue(0, 0x43211234)); + case 41: return QPair<QString, QScriptValue>("QScriptValue(0, 0x10000)", QScriptValue(0, 0x10000)); + case 42: return QPair<QString, QScriptValue>("QScriptValue(0, 0x10001)", QScriptValue(0, 0x10001)); + case 43: return QPair<QString, QScriptValue>("QScriptValue(0, qSNaN())", QScriptValue(0, qSNaN())); + case 44: return QPair<QString, QScriptValue>("QScriptValue(0, qQNaN())", QScriptValue(0, qQNaN())); + case 45: return QPair<QString, QScriptValue>("QScriptValue(0, qInf())", QScriptValue(0, qInf())); + case 46: return QPair<QString, QScriptValue>("QScriptValue(0, -qInf())", QScriptValue(0, -qInf())); + case 47: return QPair<QString, QScriptValue>("QScriptValue(0, \"NaN\")", QScriptValue(0, "NaN")); + case 48: return QPair<QString, QScriptValue>("QScriptValue(0, \"Infinity\")", QScriptValue(0, "Infinity")); + case 49: return QPair<QString, QScriptValue>("QScriptValue(0, \"-Infinity\")", QScriptValue(0, "-Infinity")); + case 50: return QPair<QString, QScriptValue>("QScriptValue(0, \"ciao\")", QScriptValue(0, "ciao")); + case 51: return QPair<QString, QScriptValue>("QScriptValue(0, QString::fromLatin1(\"ciao\"))", QScriptValue(0, QString::fromLatin1("ciao"))); + case 52: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"\"))", QScriptValue(0, QString(""))); + case 53: return QPair<QString, QScriptValue>("QScriptValue(0, QString())", QScriptValue(0, QString())); + case 54: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"0\"))", QScriptValue(0, QString("0"))); + case 55: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"123\"))", QScriptValue(0, QString("123"))); + case 56: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"12.3\"))", QScriptValue(0, QString("12.3"))); + case 57: return QPair<QString, QScriptValue>("QScriptValue(engine, QScriptValue::UndefinedValue)", QScriptValue(engine, QScriptValue::UndefinedValue)); + case 58: return QPair<QString, QScriptValue>("QScriptValue(engine, QScriptValue::NullValue)", QScriptValue(engine, QScriptValue::NullValue)); + case 59: return QPair<QString, QScriptValue>("QScriptValue(engine, true)", QScriptValue(engine, true)); + case 60: return QPair<QString, QScriptValue>("QScriptValue(engine, false)", QScriptValue(engine, false)); + case 61: return QPair<QString, QScriptValue>("QScriptValue(engine, int(122))", QScriptValue(engine, int(122))); + case 62: return QPair<QString, QScriptValue>("QScriptValue(engine, uint(124))", QScriptValue(engine, uint(124))); + case 63: return QPair<QString, QScriptValue>("QScriptValue(engine, 0)", QScriptValue(engine, 0)); + case 64: return QPair<QString, QScriptValue>("QScriptValue(engine, 0.0)", QScriptValue(engine, 0.0)); + case 65: return QPair<QString, QScriptValue>("QScriptValue(engine, 123.0)", QScriptValue(engine, 123.0)); + case 66: return QPair<QString, QScriptValue>("QScriptValue(engine, 6.37e-8)", QScriptValue(engine, 6.37e-8)); + case 67: return QPair<QString, QScriptValue>("QScriptValue(engine, -6.37e-8)", QScriptValue(engine, -6.37e-8)); + case 68: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x43211234)", QScriptValue(engine, 0x43211234)); + case 69: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x10000)", QScriptValue(engine, 0x10000)); + case 70: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x10001)", QScriptValue(engine, 0x10001)); + case 71: return QPair<QString, QScriptValue>("QScriptValue(engine, qSNaN())", QScriptValue(engine, qSNaN())); + case 72: return QPair<QString, QScriptValue>("QScriptValue(engine, qQNaN())", QScriptValue(engine, qQNaN())); + case 73: return QPair<QString, QScriptValue>("QScriptValue(engine, qInf())", QScriptValue(engine, qInf())); + case 74: return QPair<QString, QScriptValue>("QScriptValue(engine, -qInf())", QScriptValue(engine, -qInf())); + case 75: return QPair<QString, QScriptValue>("QScriptValue(engine, \"NaN\")", QScriptValue(engine, "NaN")); + case 76: return QPair<QString, QScriptValue>("QScriptValue(engine, \"Infinity\")", QScriptValue(engine, "Infinity")); + case 77: return QPair<QString, QScriptValue>("QScriptValue(engine, \"-Infinity\")", QScriptValue(engine, "-Infinity")); + case 78: return QPair<QString, QScriptValue>("QScriptValue(engine, \"ciao\")", QScriptValue(engine, "ciao")); + case 79: return QPair<QString, QScriptValue>("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", QScriptValue(engine, QString::fromLatin1("ciao"))); + case 80: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"\"))", QScriptValue(engine, QString(""))); + case 81: return QPair<QString, QScriptValue>("QScriptValue(engine, QString())", QScriptValue(engine, QString())); + case 82: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"0\"))", QScriptValue(engine, QString("0"))); + case 83: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"123\"))", QScriptValue(engine, QString("123"))); + case 84: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"1.23\"))", QScriptValue(engine, QString("1.23"))); + case 85: return QPair<QString, QScriptValue>("engine->evaluate(\"[]\")", engine->evaluate("[]")); + case 86: return QPair<QString, QScriptValue>("engine->evaluate(\"{}\")", engine->evaluate("{}")); + case 87: return QPair<QString, QScriptValue>("engine->evaluate(\"Object.prototype\")", engine->evaluate("Object.prototype")); + case 88: return QPair<QString, QScriptValue>("engine->evaluate(\"Date.prototype\")", engine->evaluate("Date.prototype")); + case 89: return QPair<QString, QScriptValue>("engine->evaluate(\"Array.prototype\")", engine->evaluate("Array.prototype")); + case 90: return QPair<QString, QScriptValue>("engine->evaluate(\"Function.prototype\")", engine->evaluate("Function.prototype")); + case 91: return QPair<QString, QScriptValue>("engine->evaluate(\"Error.prototype\")", engine->evaluate("Error.prototype")); + case 92: return QPair<QString, QScriptValue>("engine->evaluate(\"Object\")", engine->evaluate("Object")); + case 93: return QPair<QString, QScriptValue>("engine->evaluate(\"Array\")", engine->evaluate("Array")); + case 94: return QPair<QString, QScriptValue>("engine->evaluate(\"Number\")", engine->evaluate("Number")); + case 95: return QPair<QString, QScriptValue>("engine->evaluate(\"Function\")", engine->evaluate("Function")); + case 96: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { return 1; })\")", engine->evaluate("(function() { return 1; })")); + case 97: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { return 'ciao'; })\")", engine->evaluate("(function() { return 'ciao'; })")); + case 98: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { throw new Error('foo'); })\")", engine->evaluate("(function() { throw new Error('foo'); })")); + case 99: return QPair<QString, QScriptValue>("engine->evaluate(\"/foo/\")", engine->evaluate("/foo/")); + case 100: return QPair<QString, QScriptValue>("engine->evaluate(\"new Object()\")", engine->evaluate("new Object()")); + case 101: return QPair<QString, QScriptValue>("engine->evaluate(\"new Array()\")", engine->evaluate("new Array()")); + case 102: return QPair<QString, QScriptValue>("engine->evaluate(\"new Error()\")", engine->evaluate("new Error()")); + case 103: return QPair<QString, QScriptValue>("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", engine->evaluate("a = new Object(); a.foo = 22; a.foo")); + case 104: return QPair<QString, QScriptValue>("engine->evaluate(\"Undefined\")", engine->evaluate("Undefined")); + case 105: return QPair<QString, QScriptValue>("engine->evaluate(\"Null\")", engine->evaluate("Null")); + case 106: return QPair<QString, QScriptValue>("engine->evaluate(\"True\")", engine->evaluate("True")); + case 107: return QPair<QString, QScriptValue>("engine->evaluate(\"False\")", engine->evaluate("False")); + case 108: return QPair<QString, QScriptValue>("engine->evaluate(\"undefined\")", engine->evaluate("undefined")); + case 109: return QPair<QString, QScriptValue>("engine->evaluate(\"null\")", engine->evaluate("null")); + case 110: return QPair<QString, QScriptValue>("engine->evaluate(\"true\")", engine->evaluate("true")); + case 111: return QPair<QString, QScriptValue>("engine->evaluate(\"false\")", engine->evaluate("false")); + case 112: return QPair<QString, QScriptValue>("engine->evaluate(\"122\")", engine->evaluate("122")); + case 113: return QPair<QString, QScriptValue>("engine->evaluate(\"124\")", engine->evaluate("124")); + case 114: return QPair<QString, QScriptValue>("engine->evaluate(\"0\")", engine->evaluate("0")); + case 115: return QPair<QString, QScriptValue>("engine->evaluate(\"0.0\")", engine->evaluate("0.0")); + case 116: return QPair<QString, QScriptValue>("engine->evaluate(\"123.0\")", engine->evaluate("123.0")); + case 117: return QPair<QString, QScriptValue>("engine->evaluate(\"6.37e-8\")", engine->evaluate("6.37e-8")); + case 118: return QPair<QString, QScriptValue>("engine->evaluate(\"-6.37e-8\")", engine->evaluate("-6.37e-8")); + case 119: return QPair<QString, QScriptValue>("engine->evaluate(\"0x43211234\")", engine->evaluate("0x43211234")); + case 120: return QPair<QString, QScriptValue>("engine->evaluate(\"0x10000\")", engine->evaluate("0x10000")); + case 121: return QPair<QString, QScriptValue>("engine->evaluate(\"0x10001\")", engine->evaluate("0x10001")); + case 122: return QPair<QString, QScriptValue>("engine->evaluate(\"NaN\")", engine->evaluate("NaN")); + case 123: return QPair<QString, QScriptValue>("engine->evaluate(\"Infinity\")", engine->evaluate("Infinity")); + case 124: return QPair<QString, QScriptValue>("engine->evaluate(\"-Infinity\")", engine->evaluate("-Infinity")); + case 125: return QPair<QString, QScriptValue>("engine->evaluate(\"'ciao'\")", engine->evaluate("'ciao'")); + case 126: return QPair<QString, QScriptValue>("engine->evaluate(\"''\")", engine->evaluate("''")); + case 127: return QPair<QString, QScriptValue>("engine->evaluate(\"'0'\")", engine->evaluate("'0'")); + case 128: return QPair<QString, QScriptValue>("engine->evaluate(\"'123'\")", engine->evaluate("'123'")); + case 129: return QPair<QString, QScriptValue>("engine->evaluate(\"'12.4'\")", engine->evaluate("'12.4'")); + case 130: return QPair<QString, QScriptValue>("engine->nullValue()", engine->nullValue()); + case 131: return QPair<QString, QScriptValue>("engine->undefinedValue()", engine->undefinedValue()); + case 132: return QPair<QString, QScriptValue>("engine->newObject()", engine->newObject()); + case 133: return QPair<QString, QScriptValue>("engine->newArray()", engine->newArray()); + case 134: return QPair<QString, QScriptValue>("engine->newArray(10)", engine->newArray(10)); + } + Q_ASSERT(false); + return qMakePair(QString(), QScriptValue()); } diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp index f1de77d..433597f 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp @@ -25,13 +25,7 @@ #include "tst_qscriptvalue.h" -void tst_QScriptValue::isValid_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isValid_array[] = { +static const QString isValid_array[] = { "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", "QScriptValue(true)", @@ -129,12 +123,12 @@ static QString isValid_array[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -162,36 +156,37 @@ static QString isValid_array[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -void tst_QScriptValue::isValid_makeData(const char* expr) +void tst_QScriptValue::isValid_data() { - static QSet<QString> isValid; - if (isValid.isEmpty()) { - isValid.reserve(131); - for (unsigned i = 0; i < 131; ++i) - isValid.insert(isValid_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(134); + for (uint i = 0; i < 134; ++i) + expectedValue.insert(isValid_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isValid.contains(expr); } -void tst_QScriptValue::isValid_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isValid() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isValid(), expected); QCOMPARE(value.isValid(), expected); } -DEFINE_TEST_FUNCTION(isValid) - - -void tst_QScriptValue::isBool_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isBool_array[] = { +static const QString isBool_array[] = { "QScriptValue(true)", "QScriptValue(false)", "QScriptValue(0, true)", @@ -201,34 +196,32 @@ static QString isBool_array[] = { "engine->evaluate(\"true\")", "engine->evaluate(\"false\")"}; -void tst_QScriptValue::isBool_makeData(const char* expr) +void tst_QScriptValue::isBool_data() { - static QSet<QString> isBool; - if (isBool.isEmpty()) { - isBool.reserve(8); - for (unsigned i = 0; i < 8; ++i) - isBool.insert(isBool_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(8); + for (uint i = 0; i < 8; ++i) + expectedValue.insert(isBool_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isBool.contains(expr); } -void tst_QScriptValue::isBool_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isBool() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isBool(), expected); QCOMPARE(value.isBool(), expected); } -DEFINE_TEST_FUNCTION(isBool) - - -void tst_QScriptValue::isBoolean_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isBoolean_array[] = { +static const QString isBoolean_array[] = { "QScriptValue(true)", "QScriptValue(false)", "QScriptValue(0, true)", @@ -238,34 +231,32 @@ static QString isBoolean_array[] = { "engine->evaluate(\"true\")", "engine->evaluate(\"false\")"}; -void tst_QScriptValue::isBoolean_makeData(const char* expr) +void tst_QScriptValue::isBoolean_data() { - static QSet<QString> isBoolean; - if (isBoolean.isEmpty()) { - isBoolean.reserve(8); - for (unsigned i = 0; i < 8; ++i) - isBoolean.insert(isBoolean_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(8); + for (uint i = 0; i < 8; ++i) + expectedValue.insert(isBoolean_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isBoolean.contains(expr); } -void tst_QScriptValue::isBoolean_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isBoolean() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isBoolean(), expected); QCOMPARE(value.isBoolean(), expected); } -DEFINE_TEST_FUNCTION(isBoolean) - - -void tst_QScriptValue::isNumber_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isNumber_array[] = { +static const QString isNumber_array[] = { "QScriptValue(int(122))", "QScriptValue(uint(124))", "QScriptValue(0)", @@ -308,6 +299,7 @@ static QString isNumber_array[] = { "QScriptValue(engine, qQNaN())", "QScriptValue(engine, qInf())", "QScriptValue(engine, -qInf())", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"122\")", "engine->evaluate(\"124\")", "engine->evaluate(\"0\")", @@ -322,34 +314,32 @@ static QString isNumber_array[] = { "engine->evaluate(\"Infinity\")", "engine->evaluate(\"-Infinity\")"}; -void tst_QScriptValue::isNumber_makeData(const char* expr) +void tst_QScriptValue::isNumber_data() { - static QSet<QString> isNumber; - if (isNumber.isEmpty()) { - isNumber.reserve(55); - for (unsigned i = 0; i < 55; ++i) - isNumber.insert(isNumber_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(56); + for (uint i = 0; i < 56; ++i) + expectedValue.insert(isNumber_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isNumber.contains(expr); } -void tst_QScriptValue::isNumber_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isNumber() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isNumber(), expected); QCOMPARE(value.isNumber(), expected); } -DEFINE_TEST_FUNCTION(isNumber) - - -void tst_QScriptValue::isFunction_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isFunction_array[] = { +static const QString isFunction_array[] = { "engine->evaluate(\"Function.prototype\")", "engine->evaluate(\"Object\")", "engine->evaluate(\"Array\")", @@ -357,70 +347,67 @@ static QString isFunction_array[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")"}; -void tst_QScriptValue::isFunction_makeData(const char* expr) +void tst_QScriptValue::isFunction_data() { - static QSet<QString> isFunction; - if (isFunction.isEmpty()) { - isFunction.reserve(8); - for (unsigned i = 0; i < 8; ++i) - isFunction.insert(isFunction_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(9); + for (uint i = 0; i < 9; ++i) + expectedValue.insert(isFunction_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isFunction.contains(expr); } -void tst_QScriptValue::isFunction_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isFunction() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isFunction(), expected); QCOMPARE(value.isFunction(), expected); } -DEFINE_TEST_FUNCTION(isFunction) - - -void tst_QScriptValue::isNull_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isNull_array[] = { +static const QString isNull_array[] = { "QScriptValue(QScriptValue::NullValue)", "QScriptValue(0, QScriptValue::NullValue)", "QScriptValue(engine, QScriptValue::NullValue)", "engine->evaluate(\"null\")", "engine->nullValue()"}; -void tst_QScriptValue::isNull_makeData(const char* expr) +void tst_QScriptValue::isNull_data() { - static QSet<QString> isNull; - if (isNull.isEmpty()) { - isNull.reserve(5); - for (unsigned i = 0; i < 5; ++i) - isNull.insert(isNull_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(5); + for (uint i = 0; i < 5; ++i) + expectedValue.insert(isNull_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isNull.contains(expr); } -void tst_QScriptValue::isNull_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isNull() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isNull(), expected); QCOMPARE(value.isNull(), expected); } -DEFINE_TEST_FUNCTION(isNull) - - -void tst_QScriptValue::isString_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isString_array[] = { +static const QString isString_array[] = { "QScriptValue(\"NaN\")", "QScriptValue(\"Infinity\")", "QScriptValue(\"-Infinity\")", @@ -457,34 +444,32 @@ static QString isString_array[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")"}; -void tst_QScriptValue::isString_makeData(const char* expr) +void tst_QScriptValue::isString_data() { - static QSet<QString> isString; - if (isString.isEmpty()) { - isString.reserve(35); - for (unsigned i = 0; i < 35; ++i) - isString.insert(isString_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(35); + for (uint i = 0; i < 35; ++i) + expectedValue.insert(isString_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isString.contains(expr); } -void tst_QScriptValue::isString_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isString() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isString(), expected); QCOMPARE(value.isString(), expected); } -DEFINE_TEST_FUNCTION(isString) - - -void tst_QScriptValue::isUndefined_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isUndefined_array[] = { +static const QString isUndefined_array[] = { "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(0, QScriptValue::UndefinedValue)", "QScriptValue(engine, QScriptValue::UndefinedValue)", @@ -492,37 +477,35 @@ static QString isUndefined_array[] = { "engine->evaluate(\"undefined\")", "engine->undefinedValue()"}; -void tst_QScriptValue::isUndefined_makeData(const char* expr) +void tst_QScriptValue::isUndefined_data() { - static QSet<QString> isUndefined; - if (isUndefined.isEmpty()) { - isUndefined.reserve(6); - for (unsigned i = 0; i < 6; ++i) - isUndefined.insert(isUndefined_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(6); + for (uint i = 0; i < 6; ++i) + expectedValue.insert(isUndefined_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isUndefined.contains(expr); } -void tst_QScriptValue::isUndefined_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isUndefined() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isUndefined(), expected); QCOMPARE(value.isUndefined(), expected); } -DEFINE_TEST_FUNCTION(isUndefined) - - -void tst_QScriptValue::isObject_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString isObject_array[] = { +static const QString isObject_array[] = { "engine->evaluate(\"[]\")", "engine->evaluate(\"Object.prototype\")", "engine->evaluate(\"Date.prototype\")", @@ -535,33 +518,105 @@ static QString isObject_array[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", - "engine->evaluate(\"False\")"}; + "engine->evaluate(\"False\")", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -void tst_QScriptValue::isObject_makeData(const char* expr) +void tst_QScriptValue::isObject_data() { - static QSet<QString> isObject; - if (isObject.isEmpty()) { - isObject.reserve(22); - for (unsigned i = 0; i < 22; ++i) - isObject.insert(isObject_array[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(24); + for (uint i = 0; i < 24; ++i) + expectedValue.insert(isObject_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); } - newRow(expr) << isObject.contains(expr); } -void tst_QScriptValue::isObject_test(const char*, const QScriptValue& value) +void tst_QScriptValue::isObject() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.isObject(), expected); QCOMPARE(value.isObject(), expected); } -DEFINE_TEST_FUNCTION(isObject) +static const QString isArray_array[] = { + "engine->evaluate(\"[]\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"new Array()\")", + "engine->newArray()", + "engine->newArray(10)"}; + +void tst_QScriptValue::isArray_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(5); + for (uint i = 0; i < 5; ++i) + expectedValue.insert(isArray_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isArray() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isArray(), expected); + QCOMPARE(value.isArray(), expected); +} + +static const QString isError_array[] = { + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")"}; + +void tst_QScriptValue::isError_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(6); + for (uint i = 0; i < 6; ++i) + expectedValue.insert(isError_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isError() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isError(), expected); + QCOMPARE(value.isError(), expected); +} diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp index a946aef..eaa5d14 100644 --- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp @@ -23,15 +23,7 @@ #include "tst_qscriptvalue.h" - - -void tst_QScriptValue::toString_initData() -{ - QTest::addColumn<QString>("expected"); - initScriptValues(); -} - -static QString toString_tagArray[] = { +static const QString toString_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -130,12 +122,12 @@ static QString toString_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -163,9 +155,12 @@ static QString toString_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static QString toString_valueArray[] = { +static const QString toString_valueArray[] = { "", "undefined", "null", "true", "false", "122", @@ -215,9 +210,9 @@ static QString toString_valueArray[] = { "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", "function () { return 1; }", "function () { return 'ciao'; }", - "SyntaxError: Parse error", "/foo/", + "function () { throw new Error('foo'); }", "/foo/", "[object Object]", "", - "Error: Unknown error", "SyntaxError: Parse error", + "Error: Unknown error", "22", "ReferenceError: Can't find variable: Undefined", "ReferenceError: Can't find variable: Null", "ReferenceError: Can't find variable: True", "ReferenceError: Can't find variable: False", "undefined", "null", @@ -231,36 +226,36 @@ static QString toString_valueArray[] = { "-Infinity", "ciao", "", "0", "123", "12.4", - "null", "undefined"}; + "null", "undefined", + "[object Object]", "", + ",,,,,,,,,"}; -void tst_QScriptValue::toString_makeData(const char* expr) +void tst_QScriptValue::toString_data() { - static QHash<QString, QString> toString; - if (toString.isEmpty()) { - toString.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toString.insert(toString_tagArray[i], toString_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, QString> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toString_tagArray[i], toString_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toString.value(expr); } -void tst_QScriptValue::toString_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toString() { + QFETCH(QScriptValue, value); QFETCH(QString, expected); QCOMPARE(value.toString(), expected); QCOMPARE(value.toString(), expected); } -DEFINE_TEST_FUNCTION(toString) - - -void tst_QScriptValue::toNumber_initData() -{ - QTest::addColumn<qsreal>("expected"); - initScriptValues(); -} - -static QString toNumber_tagArray[] = { +static const QString toNumber_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -359,12 +354,12 @@ static QString toNumber_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -392,8 +387,12 @@ static QString toNumber_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; -static qsreal toNumber_valueArray[] = { + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const qsreal toNumber_valueArray[] = { 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), @@ -404,23 +403,31 @@ static qsreal toNumber_valueArray[] = { 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), - qQNaN(), 0, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, + qQNaN(), 0, qQNaN(), 22, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qInf(), qInf(), qQNaN(), 0, 0, 123, 12.4, - 0, qQNaN()}; -void tst_QScriptValue::toNumber_makeData(const char* expr) + 0, qQNaN(), qQNaN(), 0, qQNaN()}; + +void tst_QScriptValue::toNumber_data() { - static QHash<QString, qsreal> toNumber; - if (toNumber.isEmpty()) { - toNumber.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toNumber.insert(toNumber_tagArray[i], toNumber_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qsreal>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qsreal> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toNumber_tagArray[i], toNumber_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toNumber.value(expr); } -void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toNumber() { + QFETCH(QScriptValue, value); QFETCH(qsreal, expected); if (qIsNaN(expected)) { QVERIFY(qIsNaN(value.toNumber())); @@ -435,16 +442,7 @@ void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value) QCOMPARE(value.toNumber(), expected); } -DEFINE_TEST_FUNCTION(toNumber) - - -void tst_QScriptValue::toBool_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString toBool_tagArray[] = { +static const QString toBool_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -543,12 +541,12 @@ static QString toBool_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -576,9 +574,12 @@ static QString toBool_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static bool toBool_valueArray[] = { +static const bool toBool_valueArray[] = { false, false, false, true, false, true, @@ -644,36 +645,36 @@ static bool toBool_valueArray[] = { true, true, false, true, true, true, - false, false}; + false, false, + true, true, + true}; -void tst_QScriptValue::toBool_makeData(const char* expr) +void tst_QScriptValue::toBool_data() { - static QHash<QString, bool> toBool; - if (toBool.isEmpty()) { - toBool.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toBool.insert(toBool_tagArray[i], toBool_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, bool> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toBool_tagArray[i], toBool_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toBool.value(expr); } -void tst_QScriptValue::toBool_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toBool() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.toBool(), expected); QCOMPARE(value.toBool(), expected); } -DEFINE_TEST_FUNCTION(toBool) - - -void tst_QScriptValue::toBoolean_initData() -{ - QTest::addColumn<bool>("expected"); - initScriptValues(); -} - -static QString toBoolean_tagArray[] = { +static const QString toBoolean_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -772,12 +773,12 @@ static QString toBoolean_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -805,9 +806,12 @@ static QString toBoolean_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static bool toBoolean_valueArray[] = { +static const bool toBoolean_valueArray[] = { false, false, false, true, false, true, @@ -873,36 +877,36 @@ static bool toBoolean_valueArray[] = { true, true, false, true, true, true, - false, false}; + false, false, + true, true, + true}; -void tst_QScriptValue::toBoolean_makeData(const char* expr) +void tst_QScriptValue::toBoolean_data() { - static QHash<QString, bool> toBoolean; - if (toBoolean.isEmpty()) { - toBoolean.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toBoolean.insert(toBoolean_tagArray[i], toBoolean_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, bool> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toBoolean_tagArray[i], toBoolean_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toBoolean.value(expr); } -void tst_QScriptValue::toBoolean_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toBoolean() { + QFETCH(QScriptValue, value); QFETCH(bool, expected); QCOMPARE(value.toBoolean(), expected); QCOMPARE(value.toBoolean(), expected); } -DEFINE_TEST_FUNCTION(toBoolean) - - -void tst_QScriptValue::toInteger_initData() -{ - QTest::addColumn<qsreal>("expected"); - initScriptValues(); -} - -static QString toInteger_tagArray[] = { +static const QString toInteger_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1001,12 +1005,12 @@ static QString toInteger_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -1034,8 +1038,12 @@ static QString toInteger_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; -static qsreal toInteger_valueArray[] = { + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const qsreal toInteger_valueArray[] = { 0, 0, 0, 1, 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), 0, 0, 0, 0, 0, 123, 12, 0, @@ -1046,23 +1054,31 @@ static qsreal toInteger_valueArray[] = { 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), 0, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, 65536, 65537, 0, qInf(), qInf(), 0, 0, 0, 123, 12, - 0, 0}; -void tst_QScriptValue::toInteger_makeData(const char* expr) + 0, 0, 0, 0, 0}; + +void tst_QScriptValue::toInteger_data() { - static QHash<QString, qsreal> toInteger; - if (toInteger.isEmpty()) { - toInteger.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toInteger.insert(toInteger_tagArray[i], toInteger_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qsreal>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qsreal> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toInteger_tagArray[i], toInteger_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toInteger.value(expr); } -void tst_QScriptValue::toInteger_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toInteger() { + QFETCH(QScriptValue, value); QFETCH(qsreal, expected); if (qIsInf(expected)) { QVERIFY(qIsInf(value.toInteger())); @@ -1073,16 +1089,7 @@ void tst_QScriptValue::toInteger_test(const char*, const QScriptValue& value) QCOMPARE(value.toInteger(), expected); } -DEFINE_TEST_FUNCTION(toInteger) - - -void tst_QScriptValue::toInt32_initData() -{ - QTest::addColumn<qint32>("expected"); - initScriptValues(); -} - -static QString toInt32_tagArray[] = { +static const QString toInt32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1181,12 +1188,12 @@ static QString toInt32_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -1214,9 +1221,12 @@ static QString toInt32_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static qint32 toInt32_valueArray[] = { +static const qint32 toInt32_valueArray[] = { 0, 0, 0, 1, 0, 122, @@ -1268,7 +1278,7 @@ static qint32 toInt32_valueArray[] = { 0, 0, 0, 0, 0, 0, - 0, 0, + 0, 22, 0, 0, 0, 0, 0, 0, @@ -1282,36 +1292,36 @@ static qint32 toInt32_valueArray[] = { 0, 0, 0, 0, 123, 12, - 0, 0}; + 0, 0, + 0, 0, + 0}; -void tst_QScriptValue::toInt32_makeData(const char* expr) +void tst_QScriptValue::toInt32_data() { - static QHash<QString, qint32> toInt32; - if (toInt32.isEmpty()) { - toInt32.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toInt32.insert(toInt32_tagArray[i], toInt32_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qint32>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qint32> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toInt32_tagArray[i], toInt32_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toInt32.value(expr); } -void tst_QScriptValue::toInt32_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toInt32() { + QFETCH(QScriptValue, value); QFETCH(qint32, expected); QCOMPARE(value.toInt32(), expected); QCOMPARE(value.toInt32(), expected); } -DEFINE_TEST_FUNCTION(toInt32) - - -void tst_QScriptValue::toUInt32_initData() -{ - QTest::addColumn<quint32>("expected"); - initScriptValues(); -} - -static QString toUInt32_tagArray[] = { +static const QString toUInt32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1410,12 +1420,12 @@ static QString toUInt32_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -1443,9 +1453,12 @@ static QString toUInt32_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static quint32 toUInt32_valueArray[] = { +static const quint32 toUInt32_valueArray[] = { 0, 0, 0, 1, 0, 122, @@ -1497,7 +1510,7 @@ static quint32 toUInt32_valueArray[] = { 0, 0, 0, 0, 0, 0, - 0, 0, + 0, 22, 0, 0, 0, 0, 0, 0, @@ -1511,36 +1524,36 @@ static quint32 toUInt32_valueArray[] = { 0, 0, 0, 0, 123, 12, - 0, 0}; + 0, 0, + 0, 0, + 0}; -void tst_QScriptValue::toUInt32_makeData(const char* expr) +void tst_QScriptValue::toUInt32_data() { - static QHash<QString, quint32> toUInt32; - if (toUInt32.isEmpty()) { - toUInt32.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toUInt32.insert(toUInt32_tagArray[i], toUInt32_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<quint32>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, quint32> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toUInt32_tagArray[i], toUInt32_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toUInt32.value(expr); } -void tst_QScriptValue::toUInt32_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toUInt32() { + QFETCH(QScriptValue, value); QFETCH(quint32, expected); QCOMPARE(value.toUInt32(), expected); QCOMPARE(value.toUInt32(), expected); } -DEFINE_TEST_FUNCTION(toUInt32) - - -void tst_QScriptValue::toUInt16_initData() -{ - QTest::addColumn<quint16>("expected"); - initScriptValues(); -} - -static QString toUInt16_tagArray[] = { +static const QString toUInt16_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1639,12 +1652,12 @@ static QString toUInt16_tagArray[] = { "engine->evaluate(\"Function\")", "engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"(function() { return 'ciao'; })\")", - "engine->evaluate(\"(function() { throw new Error('foo' })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", - "engine->evaluate(\"a = new Object( a.foo = 22; a.foo\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -1672,9 +1685,12 @@ static QString toUInt16_tagArray[] = { "engine->evaluate(\"'123'\")", "engine->evaluate(\"'12.4'\")", "engine->nullValue()", - "engine->undefinedValue()"}; + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; -static quint16 toUInt16_valueArray[] = { +static const quint16 toUInt16_valueArray[] = { 0, 0, 0, 1, 0, 122, @@ -1726,7 +1742,7 @@ static quint16 toUInt16_valueArray[] = { 0, 0, 0, 0, 0, 0, - 0, 0, + 0, 22, 0, 0, 0, 0, 0, 0, @@ -1740,24 +1756,31 @@ static quint16 toUInt16_valueArray[] = { 0, 0, 0, 0, 123, 12, - 0, 0}; + 0, 0, + 0, 0, + 0}; -void tst_QScriptValue::toUInt16_makeData(const char* expr) +void tst_QScriptValue::toUInt16_data() { - static QHash<QString, quint16> toUInt16; - if (toUInt16.isEmpty()) { - toUInt16.reserve(132); - for (unsigned i = 0; i < 132; ++i) - toUInt16.insert(toUInt16_tagArray[i], toUInt16_valueArray[i]); + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<quint16>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, quint16> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toUInt16_tagArray[i], toUInt16_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; } - newRow(expr) << toUInt16.value(expr); } -void tst_QScriptValue::toUInt16_test(const char*, const QScriptValue& value) +void tst_QScriptValue::toUInt16() { + QFETCH(QScriptValue, value); QFETCH(quint16, expected); QCOMPARE(value.toUInt16(), expected); QCOMPARE(value.toUInt16(), expected); } - -DEFINE_TEST_FUNCTION(toUInt16) diff --git a/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h index 5b7adcf..e9a6c64 100644 --- a/JavaScriptCore/runtime/JSByteArray.h +++ b/JavaScriptCore/runtime/JSByteArray.h @@ -45,25 +45,18 @@ namespace JSC { void setIndex(unsigned i, int value) { ASSERT(canAccessIndex(i)); - if (value & ~0xFF) { - if (value < 0) - value = 0; - else - value = 255; - } m_storage->data()[i] = static_cast<unsigned char>(value); } - + void setIndex(unsigned i, double value) { ASSERT(canAccessIndex(i)); - if (!(value > 0)) // Clamp NaN to 0 - value = 0; - else if (value > 255) - value = 255; - m_storage->data()[i] = static_cast<unsigned char>(value + 0.5); + // The largest integer value that a double can represent without loss of precision + // is 2^53. long long is the smallest integral type that gives correct results + // when casting numbers larger than 2^31 from a value of type double. + m_storage->data()[i] = static_cast<unsigned char>(static_cast<long long>(value)); } - + void setIndex(ExecState* exec, unsigned i, JSValue value) { double byteValue = value.toNumber(exec); @@ -75,7 +68,7 @@ namespace JSC { JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo); static PassRefPtr<Structure> createStructure(JSValue prototype); - + virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); @@ -86,7 +79,7 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return m_classInfo; } static const ClassInfo s_defaultInfo; - + size_t length() const { return m_storage->length(); } WTF::ByteArray* storage() const { return m_storage.get(); } @@ -100,7 +93,7 @@ namespace JSC { private: enum VPtrStealingHackType { VPtrStealingHack }; - JSByteArray(VPtrStealingHackType) + JSByteArray(VPtrStealingHackType) : JSObject(createStructure(jsNull())) , m_classInfo(0) { @@ -109,7 +102,7 @@ namespace JSC { RefPtr<WTF::ByteArray> m_storage; const ClassInfo* m_classInfo; }; - + JSByteArray* asByteArray(JSValue value); inline JSByteArray* asByteArray(JSValue value) { diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h index 23b6b21..63f9ad8 100644 --- a/JavaScriptCore/runtime/JSGlobalData.h +++ b/JavaScriptCore/runtime/JSGlobalData.h @@ -41,6 +41,7 @@ #include "Terminator.h" #include "TimeoutChecker.h" #include "WeakRandom.h" +#include <wtf/BumpPointerAllocator.h> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> @@ -219,6 +220,8 @@ namespace JSC { RegExpCache* m_regExpCache; + BumpPointerAllocator m_regexAllocator; + #ifndef NDEBUG ThreadIdentifier exclusiveThread; #endif diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp index 69e09c1..c317e13 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -291,12 +291,12 @@ void JSGlobalObject::reset(JSValue prototype) putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum); putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum); putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor); - putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor); - putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor); - putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor); - putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor); - putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor); + putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor, DontEnum); + putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor, DontEnum); + putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor, DontEnum); + putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor, DontEnum); + putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor, DontEnum); + putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor, DontEnum); // Set global values. GlobalPropertyInfo staticGlobals[] = { diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp index d8b217d..59e3f35 100644 --- a/JavaScriptCore/runtime/RegExp.cpp +++ b/JavaScriptCore/runtime/RegExp.cpp @@ -85,8 +85,7 @@ void RegExp::compile(JSGlobalData* globalData) #if ENABLE(YARR_JIT) Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline()); #else - UNUSED_PARAM(globalData); - m_regExpBytecode.set(Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline())); + m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline()); #endif } diff --git a/JavaScriptCore/runtime/TimeoutChecker.h b/JavaScriptCore/runtime/TimeoutChecker.h index 18bc36b..71ce169 100644 --- a/JavaScriptCore/runtime/TimeoutChecker.h +++ b/JavaScriptCore/runtime/TimeoutChecker.h @@ -44,6 +44,7 @@ namespace JSC { TimeoutChecker(); void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; } + unsigned timeoutInterval() const { return m_timeoutInterval; } unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; } diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript index 99859f0..4f9d868 100644 --- a/JavaScriptCore/wscript +++ b/JavaScriptCore/wscript @@ -38,7 +38,7 @@ jscore_excludes.extend(get_excludes(jscore_dir, ['*None.cpp'])) if building_on_win32: jscore_excludes += ['ExecutableAllocatorPosix.cpp', 'MarkStackPosix.cpp', 'ThreadingPthreads.cpp'] - sources += ['jit/ExecutableAllocatorWin.cpp', 'runtime/MarkStackWin.cpp'] + sources += ['runtime/MarkStackWin.cpp'] else: jscore_excludes.append('JSStringRefBSTR.cpp') jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp'])) diff --git a/JavaScriptCore/wtf/BumpPointerAllocator.h b/JavaScriptCore/wtf/BumpPointerAllocator.h new file mode 100644 index 0000000..3deefe6 --- /dev/null +++ b/JavaScriptCore/wtf/BumpPointerAllocator.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BumpPointerAllocator_h +#define BumpPointerAllocator_h + +#include <wtf/PageAllocation.h> + +namespace WTF { + +#define MINIMUM_BUMP_POOL_SIZE 0x1000 + +class BumpPointerPool { +public: + // ensureCapacity will check whether the current pool has capacity to + // allocate 'size' bytes of memory If it does not, it will attempt to + // allocate a new pool (which will be added to this one in a chain). + // + // If allocation fails (out of memory) this method will return null. + // If the return value is non-null, then callers should update any + // references they have to this current (possibly full) BumpPointerPool + // to instead point to the newly returned BumpPointerPool. + BumpPointerPool* ensureCapacity(size_t size) + { + void* allocationEnd = static_cast<char*>(m_current) + size; + ASSERT(allocationEnd > m_current); // check for overflow + if (allocationEnd <= static_cast<void*>(this)) + return this; + return ensureCapacityCrossPool(this, size); + } + + // alloc should only be called after calling ensureCapacity; as such + // alloc will never fail. + void* alloc(size_t size) + { + void* current = m_current; + void* allocationEnd = static_cast<char*>(current) + size; + ASSERT(allocationEnd > current); // check for overflow + ASSERT(allocationEnd <= static_cast<void*>(this)); + m_current = allocationEnd; + return current; + } + + // The dealloc method releases memory allocated using alloc. Memory + // must be released in a LIFO fashion, e.g. if the client calls alloc + // four times, returning pointer A, B, C, D, then the only valid order + // in which these may be deallocaed is D, C, B, A. + // + // The client may optionally skip some deallocations. In the example + // above, it would be valid to only explicitly dealloc C, A (D being + // dealloced along with C, B along with A). + // + // If pointer was not allocated from this pool (or pools) then dealloc + // will CRASH(). Callers should update any references they have to + // this current BumpPointerPool to instead point to the returned + // BumpPointerPool. + BumpPointerPool* dealloc(void* position) + { + if ((position >= m_start) && (position <= static_cast<void*>(this))) { + ASSERT(position <= m_current); + m_current = position; + return this; + } + return deallocCrossPool(this, position); + } + +private: + // Placement operator new, returns the last 'size' bytes of allocation for use as this. + void* operator new(size_t size, const PageAllocation& allocation) + { + ASSERT(size < allocation.size()); + return reinterpret_cast<char*>(reinterpret_cast<intptr_t>(allocation.base()) + allocation.size()) - size; + } + + BumpPointerPool(const PageAllocation& allocation) + : m_current(allocation.base()) + , m_start(allocation.base()) + , m_next(0) + , m_previous(0) + , m_allocation(allocation) + { + } + + static BumpPointerPool* create(size_t minimumCapacity = 0) + { + // Add size of BumpPointerPool object, check for overflow. + minimumCapacity += sizeof(BumpPointerPool); + if (minimumCapacity < sizeof(BumpPointerPool)) + return 0; + + size_t poolSize = MINIMUM_BUMP_POOL_SIZE; + while (poolSize < minimumCapacity) { + poolSize <<= 1; + // The following if check relies on MINIMUM_BUMP_POOL_SIZE being a power of 2! + ASSERT(!(MINIMUM_BUMP_POOL_SIZE & (MINIMUM_BUMP_POOL_SIZE - 1))); + if (!poolSize) + return 0; + } + + PageAllocation allocation = PageAllocation::allocate(poolSize); + if (!!allocation) + return new(allocation) BumpPointerPool(allocation); + return 0; + } + + void shrink() + { + ASSERT(!m_previous); + m_current = m_start; + while (m_next) { + BumpPointerPool* nextNext = m_next->m_next; + m_next->destroy(); + m_next = nextNext; + } + } + + void destroy() + { + // Don't call deallocate on allocation, because allocation is *inside* allocation, + // and it will get deallocated before deallocate has completed! + PageAllocation allocation = m_allocation; + allocation.deallocate(); + } + + static BumpPointerPool* ensureCapacityCrossPool(BumpPointerPool* previousPool, size_t size) + { + // The pool passed should not have capacity, so we'll start with the next one. + ASSERT(previousPool); + ASSERT((static_cast<char*>(previousPool->m_current) + size) > previousPool->m_current); // check for overflow + ASSERT((static_cast<char*>(previousPool->m_current) + size) > static_cast<void*>(previousPool)); + BumpPointerPool* pool = previousPool->m_next; + + while (true) { + if (!pool) { + // We've run to the end; allocate a new pool. + pool = BumpPointerPool::create(size); + previousPool->m_next = pool; + pool->m_previous = previousPool; + return pool; + } + + // + void* current = pool->m_current; + void* allocationEnd = static_cast<char*>(current) + size; + ASSERT(allocationEnd > current); // check for overflow + if (allocationEnd <= static_cast<void*>(pool)) + return pool; + } + } + + static BumpPointerPool* deallocCrossPool(BumpPointerPool* pool, void* position) + { + // Should only be called if position is not in the current pool. + ASSERT((position < pool->m_start) || (position > static_cast<void*>(pool))); + + while (true) { + // Unwind the current pool to the start, move back in the chain to the previous pool. + pool->m_current = pool->m_start; + pool = pool->m_previous; + + // position was nowhere in the chain! + if (!pool) + CRASH(); + + if ((position >= pool->m_start) && (position <= static_cast<void*>(pool))) { + ASSERT(position <= pool->m_current); + pool->m_current = position; + return pool; + } + } + } + + void* m_current; + void* m_start; + BumpPointerPool* m_next; + BumpPointerPool* m_previous; + PageAllocation m_allocation; + + friend class BumpPointerAllocator; +}; + +// A BumpPointerAllocator manages a set of BumpPointerPool objects, which +// can be used for LIFO (stack like) allocation. +// +// To begin allocating using this class call startAllocator(). The result +// of this method will be null if the initial pool allocation fails, or a +// pointer to a BumpPointerPool object that can be used to perform +// allocations. Whilst running no memory will be released until +// stopAllocator() is called. At this point all allocations made through +// this allocator will be reaped, and underlying memory may be freed. +// +// (In practice we will still hold on to the initial pool to allow allocation +// to be quickly restared, but aditional pools will be freed). +// +// This allocator is non-renetrant, it is encumbant on the clients to ensure +// startAllocator() is not called again until stopAllocator() has been called. +class BumpPointerAllocator { +public: + BumpPointerAllocator() + : m_head(0) + { + } + + ~BumpPointerAllocator() + { + if (m_head) + m_head->destroy(); + } + + BumpPointerPool* startAllocator() + { + if (!m_head) + m_head = BumpPointerPool::create(); + return m_head; + } + + void stopAllocator() + { + if (m_head) + m_head->shrink(); + } + +private: + BumpPointerPool* m_head; +}; + +} + +using WTF::BumpPointerAllocator; + +#endif // BumpPointerAllocator_h diff --git a/JavaScriptCore/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt index 3e128be..3cd3c8e 100644 --- a/JavaScriptCore/wtf/CMakeListsEfl.txt +++ b/JavaScriptCore/wtf/CMakeListsEfl.txt @@ -3,15 +3,19 @@ ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1) LIST(APPEND WTF_SOURCES efl/MainThreadEfl.cpp - gobject/GOwnPtr.cpp - gobject/GRefPtr.cpp - ThreadIdentifierDataPthreads.cpp ThreadingPthreads.cpp unicode/icu/CollatorICU.cpp ) +IF (ENABLE_GLIB_SUPPORT) + LIST(APPEND WTF_SOURCES + gobject/GOwnPtr.cpp + gobject/GRefPtr.cpp + ) +ENDIF () + LIST(APPEND WTF_LIBRARIES pthread ${ICU_LIBRARIES} diff --git a/JavaScriptCore/wtf/PageAllocation.cpp b/JavaScriptCore/wtf/PageAllocation.cpp new file mode 100644 index 0000000..58a10f6 --- /dev/null +++ b/JavaScriptCore/wtf/PageAllocation.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PageAllocation.h" + +#if HAVE(ERRNO_H) +#include <errno.h> +#endif + +#if HAVE(MMAP) +#include <sys/mman.h> +#include <unistd.h> +#endif + +#if OS(WINDOWS) +#include "windows.h" +#endif + +#if OS(SYMBIAN) +#include <e32hal.h> +#endif + +namespace WTF { + +#if HAVE(MMAP) + +bool PageAllocation::commit(void* start, size_t size, bool, bool) const +{ +#if HAVE(MADV_FREE_REUSE) + while (madvise(start, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { } +#else + UNUSED_PARAM(start); + UNUSED_PARAM(size); +#endif + return true; +} + +void PageAllocation::decommit(void* start, size_t size) const +{ +#if HAVE(MADV_FREE_REUSE) + while (madvise(start, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } +#elif HAVE(MADV_FREE) + while (madvise(start, size, MADV_FREE) == -1 && errno == EAGAIN) { } +#elif HAVE(MADV_DONTNEED) + while (madvise(start, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { } +#else + UNUSED_PARAM(start); + UNUSED_PARAM(size); +#endif +} + +PageAllocation PageAllocation::allocate(size_t size, Usage usage, bool writable, bool executable) +{ + return allocateAt(0, false, size, usage, writable, executable); +} + +PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable) +{ + return reserveAt(0, false, size, usage, writable, executable); +} + +PageAllocation PageAllocation::allocateAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable) +{ + int flags = MAP_PRIVATE | MAP_ANON; + if (fixed) + flags |= MAP_FIXED; + + int protection = PROT_READ; + if (writable) + protection |= PROT_WRITE; + if (executable) + protection |= PROT_EXEC; + + void* base = mmap(address, size, protection, flags, usage, 0); + if (base == MAP_FAILED) + base = 0; + + return PageAllocation(base, size); +} + +PageAllocation PageAllocation::reserveAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable) +{ + PageAllocation result = allocateAt(address, fixed, size, usage, writable, executable); + if (!!result) + result.decommit(result.base(), size); + return result; +} + +void PageAllocation::deallocate() +{ + int result = munmap(m_base, m_size); + ASSERT_UNUSED(result, !result); + m_base = 0; +} + +size_t PageAllocation::pagesize() +{ + static size_t size = 0; + if (!size) + size = getpagesize(); + return size; +} + +#elif HAVE(VIRTUALALLOC) + +static DWORD protection(bool writable, bool executable) +{ + if (executable) + return writable ?PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + return writable ?PAGE_READWRITE : PAGE_READONLY; +} + +bool PageAllocation::commit(void* start, size_t size, bool writable, bool executable) const +{ + return VirtualAlloc(start, size, MEM_COMMIT, protection(writable, executable)) == start; +} + +void PageAllocation::decommit(void* start, size_t size) const +{ + VirtualFree(start, size, MEM_DECOMMIT); +} + +PageAllocation PageAllocation::allocate(size_t size, Usage, bool writable, bool executable) +{ + return PageAllocation(VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, protection(writable, executable)), size); +} + +PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable) +{ + return PageAllocation(VirtualAlloc(0, size, MEM_RESERVE, protection(writable, executable)), size); +} + +void PageAllocation::deallocate() +{ + VirtualFree(m_base, 0, MEM_RELEASE); + m_base = 0; +} + +size_t PageAllocation::pagesize() +{ + static size_t size = 0; + if (!size) { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + size = system_info.dwPageSize; + } + return size; +} + +#elif OS(SYMBIAN) + +bool PageAllocation::commit(void* start, size_t size, bool writable, bool executable) const +{ + if (m_chunk) { + intptr_t offset = static_cast<intptr_t>(base()) - static_cast<intptr_t>(start); + m_chunk->Commit(offset, size); + } + return true; +} + +void PageAllocation::decommit(void* start, size_t size) const +{ + if (m_chunk) { + intptr_t offset = static_cast<intptr_t>(base()) - static_cast<intptr_t>(start); + m_chunk->Decommit(offset, size); + } +} + +PageAllocation PageAllocation::allocate(size_t size, Usage usage, bool writable, bool executable) +{ + if (!executable) + return PageAllocation(fastMalloc(size), size, 0); + RChunk* rchunk = new RChunk(); + TInt errorCode = rchunk->CreateLocalCode(size, size); + return PageAllocation(rchunk->Base(), size, rchunk); +} + +PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable) +{ + if (!executable) + return PageAllocation(fastMalloc(size), size, 0); + RChunk* rchunk = new RChunk(); + TInt errorCode = rchunk->CreateLocalCode(0, size); + return PageAllocation(rchunk, rchunk->Base(), size); +} + +void PageAllocation::deallocate() +{ + if (m_chunk) { + m_chunk->Close(); + delete m_chunk; + } else + fastFree(m_base); + m_base = 0; +} + +size_t PageAllocation::pagesize() +{ + static TInt page_size = 0; + if (!page_size) + UserHal::PageSizeInBytes(page_size); + return page_size; +} + +#endif + +} diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h new file mode 100644 index 0000000..00b5363 --- /dev/null +++ b/JavaScriptCore/wtf/PageAllocation.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PageAllocation_h +#define PageAllocation_h + +#include <wtf/UnusedParam.h> +#include <wtf/VMTags.h> + +#if OS(SYMBIAN) +#include <e32std.h> +#endif + +#if HAVE(MMAP) +#define PAGE_ALLOCATION_ALLOCATE_AT 1 +#else +#define PAGE_ALLOCATION_ALLOCATE_AT 0 +#endif + +namespace WTF { + +class PageAllocation { +public: + enum Usage { + UnknownUsage = -1, + FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY, + JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY, + JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY, + JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, + }; + + PageAllocation() + : m_base(0) + , m_size(0) +#if OS(SYMBIAN) + , m_chunk(0) +#endif + { + } + + // Create a PageAllocation object representing a sub-region of an existing allocation; + // deallocate should never be called on an object represnting a subregion, only on the + // initial allocation. + PageAllocation(void* base, size_t size, const PageAllocation& parent) + : m_base(base) + , m_size(size) +#if OS(SYMBIAN) + , m_chunk(parent.chunk) +#endif + { +#if defined(NDEBUG) && !OS(SYMBIAN) + UNUSED_PARAM(parent); +#endif + ASSERT(base >= parent.m_base); + ASSERT(size <= parent.m_size); + ASSERT(static_cast<char*>(base) + size <= static_cast<char*>(parent.m_base) + parent.m_size); + } + + void* base() const { return m_base; } + size_t size() const { return m_size; } + + bool operator!() const { return !m_base; } + + bool commit(void*, size_t, bool writable = true, bool executable = false) const; + void decommit(void*, size_t) const; + void deallocate(); + + static PageAllocation allocate(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); + static PageAllocation reserve(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); +#if PAGE_ALLOCATION_ALLOCATE_AT + static PageAllocation allocateAt(void* address, bool fixed, size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); + static PageAllocation reserveAt(void* address, bool fixed, size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); +#endif + static size_t pagesize(); + +private: +#if OS(SYMBIAN) + PageAllocation(void* base, size_t size, RChunk* chunk) + : m_base(base) + , m_size(size) + , m_chunk(chunk) + { + } +#else + PageAllocation(void* base, size_t size) + : m_base(base) + , m_size(size) + { + } +#endif + + void* m_base; + size_t m_size; +#if OS(SYMBIAN) + RChunk* m_chunk; +#endif +}; + +} + +using WTF::PageAllocation; + +#endif // PageAllocation_h diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 4166ad9..ed618b0 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -80,6 +80,10 @@ #if defined(__GNUC__) && !COMPILER(RVCT) #define WTF_COMPILER_GCC 1 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch)) +#else +/* define this for !GCC compilers, just so we can write things like COMPILER(GCC) && GCC_VERSION_AT_LEAST(4,1,0) */ +#define GCC_VERSION_AT_LEAST(major, minor, patch) 0 #endif /* COMPILER(MINGW) - MinGW GCC */ @@ -522,6 +526,7 @@ #define WTF_USE_CORE_TEXT 1 #else #define WTF_PLATFORM_SKIA 1 +#define WTF_USE_GLES2_RENDERING 1 #endif #endif @@ -548,16 +553,6 @@ #endif #if OS(WINCE) && !PLATFORM(QT) -#undef ENABLE_JSC_MULTIPLE_THREADS -#define ENABLE_JSC_MULTIPLE_THREADS 0 -#define USE_SYSTEM_MALLOC 0 -#define ENABLE_ICONDATABASE 0 -#define ENABLE_JAVASCRIPT_DEBUGGER 0 -#define ENABLE_FTPDIR 0 -#define ENABLE_PAN_SCROLLING 0 -#define ENABLE_WML 1 -#define HAVE_ACCESSIBILITY 0 - #define NOMINMAX /* Windows min and max conflict with standard macros */ #define NOSHLWAPI /* shlwapi.h not available on WinCe */ @@ -650,7 +645,13 @@ This prevents unnecessary invals. */ #define ENABLE_TEXT_CARET 1 #define ENABLE_JAVASCRIPT_DEBUGGER 0 +<<<<<<< HEAD #define ENABLE_ORIENTATION_EVENTS 1 +======= +#if !defined(ENABLE_JIT) && !ENABLE(ANDROID_JSC_JIT) +#define ENABLE_JIT 0 +#endif +>>>>>>> webkit.org at r64264 #endif #if PLATFORM(WIN) @@ -936,86 +937,50 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_REPAINT_THROTTLING 0 #endif -#if !defined(ENABLE_JIT) - -/* The JIT is tested & working on x86_64 Mac */ -#if CPU(X86_64) && PLATFORM(MAC) - #define ENABLE_JIT 1 -/* The JIT is tested & working on x86 Mac */ -#elif CPU(X86) && PLATFORM(MAC) - #define ENABLE_JIT 1 -#elif CPU(ARM_THUMB2) && PLATFORM(IPHONE) - #define ENABLE_JIT 1 -/* The JIT is tested & working on Android */ -#elif CPU(ARM_THUMB2) && PLATFORM(ANDROID) && ENABLE(ANDROID_JSC_JIT) - #define ENABLE_JIT 1 -/* The JIT is tested & working on x86 Windows */ -#elif CPU(X86) && PLATFORM(WIN) - #define ENABLE_JIT 1 -#endif - -#if PLATFORM(QT) || PLATFORM(WX) -#if CPU(X86_64) && OS(DARWIN) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(DARWIN) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(ARM_TRADITIONAL) && OS(LINUX) - #define ENABLE_JIT 1 -#elif CPU(ARM_TRADITIONAL) && OS(SYMBIAN) && COMPILER(RVCT) - #define ENABLE_JIT 1 -#elif CPU(MIPS) && OS(LINUX) - #define ENABLE_JIT 1 -#endif -#endif /* PLATFORM(QT) */ - -#endif /* !defined(ENABLE_JIT) */ - -#if !ENABLE(JIT) -#define ENABLE_INTERPRETER 1 +/* Disable the JIT on versiond of GCC prior to 4.1 */ +#if !defined(ENABLE_JIT) && COMPILER(GCC) && !GCC_VERSION_AT_LEAST(4,1,0) +#define ENABLE_JIT 0 #endif -#if !(ENABLE(JIT) || ENABLE(INTERPRETER)) -#error You have to have at least one execution model enabled to build JSC +/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */ +#if !defined(ENABLE_JIT) \ + && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \ + && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4,1,0)) +#define ENABLE_JIT 1 #endif -/* CPU architecture specific optimizations */ -#if CPU(ARM_TRADITIONAL) -#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_MOD) && WTF_ARM_ARCH_AT_LEAST(5) -#define ENABLE_JIT_OPTIMIZE_MOD 1 -#endif -#endif -#if (CPU(X86) && USE(JSVALUE32_64)) || (CPU(X86_64) && USE(JSVALUE64)) \ - || CPU(ARM) \ - || CPU(MIPS) -#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) -#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 +/* Ensure that either the JIT or the interpreter has been enabled. */ +#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT) +#define ENABLE_INTERPRETER 1 #endif +#if !(ENABLE(JIT) || ENABLE(INTERPRETER)) +#error You have to have at least one execution model enabled to build JSC #endif +/* Configure the JIT */ #if ENABLE(JIT) -#ifndef ENABLE_JIT_OPTIMIZE_CALL -#define ENABLE_JIT_OPTIMIZE_CALL 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL -#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS -#define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS -#define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_MOD -#define ENABLE_JIT_OPTIMIZE_MOD 0 -#endif + #if CPU(ARM_TRADITIONAL) + #if !defined(ENABLE_JIT_USE_SOFT_MODULO) && WTF_ARM_ARCH_AT_LEAST(5) + #define ENABLE_JIT_USE_SOFT_MODULO 1 + #endif + #endif + + #if !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) && CPU(X86) && USE(JSVALUE32) + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 + #endif + + #ifndef ENABLE_JIT_OPTIMIZE_CALL + #define ENABLE_JIT_OPTIMIZE_CALL 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS + #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS + #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 + #endif #endif #if CPU(X86) && COMPILER(MSVC) @@ -1026,25 +991,20 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define JSC_HOST_CALL #endif +/* Configure the interpreter */ #if COMPILER(GCC) #define HAVE_COMPUTED_GOTO 1 #endif - #if HAVE(COMPUTED_GOTO) && ENABLE(INTERPRETER) #define ENABLE_COMPUTED_GOTO_INTERPRETER 1 #endif -/* Yet Another Regex Runtime. */ -#if !defined(ENABLE_YARR_JIT) - -/* YARR and YARR_JIT is usually turned on for JIT enabled ports */ -#if ENABLE(JIT) +/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */ +#if ENABLE(JIT) && !defined(ENABLE_YARR) && !defined(ENABLE_YARR_JIT) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif -#endif /* !defined(ENABLE_YARR_JIT) */ - /* Sanity Check */ #if ENABLE(YARR_JIT) && !ENABLE(YARR) #error "YARR_JIT requires YARR" @@ -1100,7 +1060,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ /* FIXME: Defining ENABLE_3D_RENDERING here isn't really right, but it's always used with with WTF_USE_ACCELERATED_COMPOSITING, and it allows the feature to be turned on and off in one place. */ -#if PLATFORM(WIN) +#if PLATFORM(WIN) && !OS(WINCE) #include "QuartzCorePresent.h" #if QUARTZCORE_PRESENT #define WTF_USE_ACCELERATED_COMPOSITING 1 diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h index 8a73e13..240b497 100644 --- a/JavaScriptCore/wtf/TCSpinLock.h +++ b/JavaScriptCore/wtf/TCSpinLock.h @@ -1,4 +1,5 @@ // Copyright (c) 2005, 2006, Google Inc. +// Copyright (c) 2010, Patrick Gansterer <paroga@paroga.com> // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -189,6 +190,44 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) { } } +#elif OS(WINDOWS) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +static void TCMalloc_SlowLock(LPLONG lockword); + +// The following is a struct so that it can be initialized at compile time +struct TCMalloc_SpinLock { + + inline void Lock() { + if (InterlockedExchange(&m_lockword, 1)) + TCMalloc_SlowLock(&m_lockword); + } + + inline void Unlock() { + InterlockedExchange(&m_lockword, 0); + } + + inline bool IsHeld() const { + return m_lockword != 0; + } + + inline void Init() { m_lockword = 0; } + + LONG m_lockword; +}; + +#define SPINLOCK_INITIALIZER { 0 } + +static void TCMalloc_SlowLock(LPLONG lockword) { + Sleep(0); // Yield immediately since fast path failed + while (InterlockedExchange(lockword, 1)) + Sleep(2); +} + #else #include <pthread.h> diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp index 4fb5f92..d50c6c8 100644 --- a/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -28,6 +28,7 @@ #include "RegexCompiler.h" #include "RegexPattern.h" +#include <wtf/BumpPointerAllocator.h> #ifndef NDEBUG #include <stdio.h> @@ -104,12 +105,16 @@ public: DisjunctionContext* allocDisjunctionContext(ByteDisjunction* disjunction) { - return new(malloc(sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) DisjunctionContext(); + size_t size = sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t); + allocatorPool = allocatorPool->ensureCapacity(size); + if (!allocatorPool) + CRASH(); + return new(allocatorPool->alloc(size)) DisjunctionContext(); } void freeDisjunctionContext(DisjunctionContext* context) { - free(context); + allocatorPool = allocatorPool->dealloc(context); } struct ParenthesesDisjunctionContext @@ -150,12 +155,16 @@ public: ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, int* output, ByteTerm& term) { - return new(malloc(sizeof(ParenthesesDisjunctionContext) + (((term.atom.parenthesesDisjunction->m_numSubpatterns << 1) - 1) * sizeof(int)) + sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) ParenthesesDisjunctionContext(output, term); + size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(int) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(int) + sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t); + allocatorPool = allocatorPool->ensureCapacity(size); + if (!allocatorPool) + CRASH(); + return new(allocatorPool->alloc(size)) ParenthesesDisjunctionContext(output, term); } void freeParenthesesDisjunctionContext(ParenthesesDisjunctionContext* context) { - free(context); + allocatorPool = allocatorPool->dealloc(context); } class InputStream { @@ -1190,6 +1199,10 @@ public: int interpret() { + allocatorPool = pattern->m_allocator->startAllocator(); + if (!allocatorPool) + CRASH(); + for (unsigned i = 0; i < ((pattern->m_body->m_numSubpatterns + 1) << 1); ++i) output[i] = -1; @@ -1202,6 +1215,8 @@ public: freeDisjunctionContext(context); + pattern->m_allocator->stopAllocator(); + return output[0]; } @@ -1209,6 +1224,7 @@ public: : pattern(pattern) , output(output) , input(inputChar, start, length) + , allocatorPool(0) { } @@ -1216,6 +1232,7 @@ private: BytecodePattern *pattern; int* output; InputStream input; + BumpPointerPool* allocatorPool; }; @@ -1238,13 +1255,13 @@ public: m_currentAlternativeIndex = 0; } - PassOwnPtr<BytecodePattern> compile() + PassOwnPtr<BytecodePattern> compile(BumpPointerAllocator* allocator) { regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize); emitDisjunction(m_pattern.m_body); regexEnd(); - return adoptPtr(new BytecodePattern(m_bodyDisjunction.release(), m_allParenthesesInfo, m_pattern)); + return adoptPtr(new BytecodePattern(m_bodyDisjunction.release(), m_allParenthesesInfo, m_pattern, allocator)); } void checkInput(unsigned count) @@ -1574,7 +1591,7 @@ private: }; -PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline) +PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsigned& numSubpatterns, const char*& error, BumpPointerAllocator* allocator, bool ignoreCase, bool multiline) { RegexPattern pattern(ignoreCase, multiline); @@ -1583,7 +1600,7 @@ PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsig numSubpatterns = pattern.m_numSubpatterns; - return ByteCompiler(pattern).compile(); + return ByteCompiler(pattern).compile(allocator); } int interpretRegex(BytecodePattern* regex, const UChar* input, unsigned start, unsigned length, int* output) diff --git a/JavaScriptCore/yarr/RegexInterpreter.h b/JavaScriptCore/yarr/RegexInterpreter.h index af63a7b..4da9cc5 100644 --- a/JavaScriptCore/yarr/RegexInterpreter.h +++ b/JavaScriptCore/yarr/RegexInterpreter.h @@ -33,6 +33,11 @@ #include <wtf/PassOwnPtr.h> #include <wtf/unicode/Unicode.h> +namespace WTF { +class BumpPointerAllocator; +} +using WTF::BumpPointerAllocator; + namespace JSC { namespace Yarr { class ByteDisjunction; @@ -293,10 +298,11 @@ public: }; struct BytecodePattern : FastAllocBase { - BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern) + BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern, BumpPointerAllocator* allocator) : m_body(body) , m_ignoreCase(pattern.m_ignoreCase) , m_multiline(pattern.m_multiline) + , m_allocator(allocator) { newlineCharacterClass = pattern.newlineCharacterClass(); wordcharCharacterClass = pattern.wordcharCharacterClass(); @@ -318,7 +324,10 @@ struct BytecodePattern : FastAllocBase { OwnPtr<ByteDisjunction> m_body; bool m_ignoreCase; bool m_multiline; - + // Each BytecodePattern is associated with a RegExp, each RegExp is associated + // with a JSGlobalData. Cache a pointer to out JSGlobalData's m_regexAllocator. + BumpPointerAllocator* m_allocator; + CharacterClass* newlineCharacterClass; CharacterClass* wordcharCharacterClass; private: @@ -326,7 +335,7 @@ private: Vector<CharacterClass*> m_userCharacterClasses; }; -PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false); +PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& pattern, unsigned& numSubpatterns, const char*& error, BumpPointerAllocator*, bool ignoreCase = false, bool multiline = false); int interpretRegex(BytecodePattern* v_regex, const UChar* input, unsigned start, unsigned length, int* output); } } // namespace JSC::Yarr |