diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore')
129 files changed, 5213 insertions, 2214 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/API/APICast.h b/src/3rdparty/webkit/JavaScriptCore/API/APICast.h index b6d15320aa..b9167a80ef 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/APICast.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/APICast.h @@ -27,6 +27,7 @@ #define APICast_h #include "JSAPIValueWrapper.h" +#include "JSGlobalObject.h" #include "JSValue.h" #include <wtf/Platform.h> #include <wtf/UnusedParam.h> @@ -118,6 +119,7 @@ inline JSContextRef toRef(JSC::ExecState* e) inline JSGlobalContextRef toGlobalRef(JSC::ExecState* e) { + ASSERT(e == e->lexicalGlobalObject()->globalExec()); return reinterpret_cast<JSGlobalContextRef>(e); } diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h index 202b119502..c4bd7ad3c8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h @@ -41,9 +41,12 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } +protected: + static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h index 3a17fa2de0..0cf25c4362 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h @@ -41,7 +41,7 @@ public: // refactor the code so this override isn't necessary static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h index 86f2f32c21..d19890a884 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h @@ -50,9 +50,12 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } +protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags; + private: virtual UString className() const; diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp index c358a8426a..e6626b7060 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "JSContextRef.h" +#include "JSContextRefPrivate.h" #include "APICast.h" #include "InitializeThreading.h" @@ -152,3 +153,12 @@ JSContextGroupRef JSContextGetGroup(JSContextRef ctx) ExecState* exec = toJS(ctx); return toRef(&exec->globalData()); } + +JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) +{ + ExecState* exec = toJS(ctx); + exec->globalData().heap.registerThread(); + JSLock lock(exec); + + return toGlobalRef(exec->lexicalGlobalObject()->globalExec()); +} diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h new file mode 100644 index 0000000000..ff014ec64e --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 JSContextRefPrivate_h +#define JSContextRefPrivate_h + +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSValueRef.h> +#include <JavaScriptCore/WebKitAvailability.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +@function +@abstract Gets the global context of a JavaScript execution context. +@param ctx The JSContext whose global context you want to get. +@result ctx's global context. +*/ +JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* JSContextRefPrivate_h */ diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 05f90b994e..0cbb3a5da4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,17 +1,1777 @@ -2009-09-30 Csaba Osztrogonac <oszi@inf.u-szeged.hu> +2009-11-16 Joerg Bornemann <joerg.bornemann@trolltech.com> + + Reviewed by Simon Hausmann. + + Fix Qt build on Windows CE 6. + + * JavaScriptCore.pri: Add missing include path. + * wtf/Platform.h: Include ce_time.h for Windows CE 6. + +2009-11-12 Thiago Macieira <thiago.macieira@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix linking on Linux 32-bit. + + It was missing the ".text" directive at the top of the file, + indicating that code would follow. Without it, the assembler created + "NOTYPE" symbols, which would result in linker errors. + https://bugs.webkit.org/show_bug.cgi?id=30863 + + * jit/JITStubs.cpp: + +2009-11-13 İsmail Dönmez <ismail@namtrac.org> + + Reviewed by Antti Koivisto. + + Fix typo, ce_time.cpp should be ce_time.c + + * JavaScriptCore.pri: + +2009-11-12 Richard Moe Gustavsen <richard.gustavsen@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Disable pthread_setname_np. + + This allows Qt builds on Mac from 10.6 to run on earlier version + where this symbol is not present. + https://bugs.webkit.org/show_bug.cgi?id=31403 + + * wtf/Platform.h: + +2009-11-02 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + REGRESSION (r48573): JSC may incorrectly cache chain lookups with a dictionary at the head of the chain + https://bugs.webkit.org/show_bug.cgi?id=31045 + + Add guards to prevent caching of prototype chain lookups with dictionaries at the + head of the chain. Also add a few tighter assertions to cached prototype lookups + to catch this in future. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCacheGetByID): + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCacheGetByID): + +2009-10-30 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> Reviewed by NOBODY (OOPS!). + [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 + +2009-10-29 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Add cacheFlush support for Thumb-2 on Linux + https://bugs.webkit.org/show_bug.cgi?id=30865 + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-10-28 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + JSC JIT on ARMv7 cannot link jumps >16Mb range + https://bugs.webkit.org/show_bug.cgi?id=30891 + + Start planing all relative jumps as move-32-bit-immediate-to-register-BX. + In the cases where the jump would fall within a relative jump range, use a relative jump. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::~ARMv7Assembler): + (JSC::ARMv7Assembler::LinkRecord::LinkRecord): + (JSC::ARMv7Assembler::): + (JSC::ARMv7Assembler::executableCopy): + (JSC::ARMv7Assembler::linkJump): + (JSC::ARMv7Assembler::relinkJump): + (JSC::ARMv7Assembler::setInt32): + (JSC::ARMv7Assembler::isB): + (JSC::ARMv7Assembler::isBX): + (JSC::ARMv7Assembler::isMOV_imm_T3): + (JSC::ARMv7Assembler::isMOVT): + (JSC::ARMv7Assembler::isNOP_T1): + (JSC::ARMv7Assembler::isNOP_T2): + (JSC::ARMv7Assembler::linkJumpAbsolute): + (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst): + (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond): + (JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp5i6Imm4Reg4EncodedImm): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::makeJump): + (JSC::MacroAssemblerARMv7::makeBranch): + * jit/JIT.h: + * wtf/Platform.h: + +2009-10-28 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Improve for..in enumeration performance + https://bugs.webkit.org/show_bug.cgi?id=30887 + + Improve indexing of an object with a for..in iterator by + identifying cases where get_by_val is being used with a iterator + as the subscript and replace it with a new get_by_pname + bytecode. get_by_pname then optimizes lookups that directly access + the base object. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetByVal): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::pushOptimisedForIn): + (JSC::BytecodeGenerator::popOptimisedForIn): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::emit_op_get_by_pname): + (JSC::JIT::emitSlow_op_get_by_pname): + * parser/Nodes.cpp: + (JSC::ForInNode::emitBytecode): + * runtime/JSObject.h: + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::getOffset): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + * runtime/JSValue.h: + (JSC::JSValue::): + * runtime/Structure.cpp: + (JSC::Structure::addPropertyTransition): + (JSC::Structure::changePrototypeTransition): + (JSC::Structure::despecifyFunctionTransition): + (JSC::Structure::addAnonymousSlotsTransition): + (JSC::Structure::getterSetterTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::addPropertyWithoutTransition): + Track the existence (or not) of non-enumerable properties. + * runtime/Structure.h: + (JSC::Structure::propertyStorageCapacity): + (JSC::Structure::propertyStorageSize): + (JSC::Structure::hasNonEnumerableProperties): + (JSC::Structure::hasAnonymousSlots): + +2009-10-28 Dmitry Titov <dimich@chromium.org> + + Not reviewed, attemp to fix Windows build. + + Touch the cpp file to cause recompile. + + * wtf/Threading.cpp: + (WTF::threadEntryPoint): + +2009-10-28 Dmitry Titov <dimich@chromium.org> + + Reviewed by David Levin. + + https://bugs.webkit.org/show_bug.cgi?id=30805 + Add MessageQueue::removeIf(Predicate&) to remove certain tasks without pulling them from the queue. + Existing Database tests cover this since Database removes tasks when it is stopped. + + * wtf/MessageQueue.h: + (WTF::::removeIf): + +2009-10-28 Afonso R. Costa Jr. <afonso.costa@openbossa.org> + + Reviewed by Oliver Hunt. + + [Qt] Enable YARR when YARR_JIT is enabled + https://bugs.webkit.org/show_bug.cgi?id=30730 + + When enabling or disabling JIT using JAVASCRIPTCORE_JIT, the ENABLE_YARR should + be toggled also. + + * JavaScriptCore.pri: + +2009-10-24 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Oliver Hunt. + + Fix strict aliasing warning by switching reinterpret_cast to bitwise_cast. + + strict-aliasing warnings in JSFunction.h + https://bugs.webkit.org/show_bug.cgi?id=27869 + + * runtime/JSFunction.h: + (JSC::JSFunction::nativeFunction): + (JSC::JSFunction::scopeChain): + (JSC::JSFunction::setScopeChain): + (JSC::JSFunction::setNativeFunction): + +2009-10-28 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Build-fix for 64-bit Windows + + * wtf/Platform.h: Make sure to use WTF_USE_JSVALUE64 + +2009-10-28 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix!). + + * jit/JIT.h: + +2009-10-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Rubber-stamped by Darin Adler. + + Export fastMalloc, fastCalloc, fastRealloc and fastFree on GCC/Unix + https://bugs.webkit.org/show_bug.cgi?id=30769 + + When using -fvisibility=hidden to hide all internal symbols by default + the malloc symbols will be hidden as well. For memory instrumentation + it is needed to provide an instrumented version of these symbols and + override the normal routines and by changing the visibility back to + default this becomes possible. + + The only other solution would be to use system malloc instead of the + TCmalloc implementation but this will not allow to analyze memory + behavior with the default allocator. + + * wtf/FastMalloc.h: Define WTF_FAST_MALLOC_EXPORT for GCC and !darwin + +2009-10-27 Gavin Barraclough <barraclough@apple.com> + + Rubber Stamped by Samuel Q. Weinig. + + Make the asserts protecting the offsets in the JIT more descriptive. + + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compileGetByIdSlowCase): + (JSC::JIT::emit_op_put_by_id): + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + A little bit of refactoring in the date code. + + * JavaScriptCore.exp: Don't export this unused symbol. + + * runtime/DateConstructor.cpp: + (JSC::constructDate): + + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + * runtime/DateInstance.h: Removed some unused functions. Changed the default + constructor to ensure that a DateInstance is always initialized. + + * runtime/DatePrototype.cpp: + (JSC::DatePrototype::DatePrototype): Pass an initializer to our constructor, + since it now requires one. + + * wtf/DateMath.cpp: + (WTF::msToGregorianDateTime): Only compute our offset from UTC if our + output will require it. Otherwise, our offset is 0. + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Build fix: Mark DateInstaceCache.h private, so other frameworks can see it. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Build fix: re-readded this file. + + * runtime/DateInstanceCache.h: Added. + (JSC::DateInstanceData::create): + (JSC::DateInstanceData::DateInstanceData): + (JSC::DateInstanceCache::DateInstanceCache): + (JSC::DateInstanceCache::add): + (JSC::DateInstanceCache::lookup): + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Darin Adler and Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=30800 + Cache recently computed date data. + + SunSpider reports a ~0.5% speedup, mostly from date-format-tofte.js. + + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: Added new file. + + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + (JSC::DateInstance::getGregorianDateTime): Use the shared cache. + + * runtime/DateInstance.h: Renamed m_cache to m_data, to avoid the confusion + of a "cache cache". + + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToISOString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncGetFullYear): + (JSC::dateProtoFuncGetUTCFullYear): + (JSC::dateProtoFuncToGMTString): + (JSC::dateProtoFuncGetMonth): + (JSC::dateProtoFuncGetUTCMonth): + (JSC::dateProtoFuncGetDate): + (JSC::dateProtoFuncGetUTCDate): + (JSC::dateProtoFuncGetDay): + (JSC::dateProtoFuncGetUTCDay): + (JSC::dateProtoFuncGetHours): + (JSC::dateProtoFuncGetUTCHours): + (JSC::dateProtoFuncGetMinutes): + (JSC::dateProtoFuncGetUTCMinutes): + (JSC::dateProtoFuncGetSeconds): + (JSC::dateProtoFuncGetUTCSeconds): + (JSC::dateProtoFuncGetTimezoneOffset): + (JSC::setNewValueFromTimeArgs): + (JSC::setNewValueFromDateArgs): + (JSC::dateProtoFuncSetYear): + (JSC::dateProtoFuncGetYear): Pass an ExecState to these functions, so they + can access the DateInstanceCache. + + * runtime/JSGlobalData.h: Keep a DateInstanceCache. + +2009-10-27 James Robinson <jamesr@chromium.org> + + Reviewed by Darin Fisher. + + Ensures that JavaScriptCore/wtf/CurrentTime.cpp is not built in PLATFORM(CHROMIUM) builds. + + Chromium uses a different method to calculate the current time than is used in + JavaScriptCore/wtf/CurrentTime.cpp. This can lead to time skew when calls to currentTime() and Chromium's time + function are mixed. In particular, timers can get scheduled in the past which leads to 100% CPU use. + See http://code.google.com/p/chromium/issues/detail?id=25892 for an example. + + https://bugs.webkit.org/show_bug.cgi?id=30833 + + * JavaScriptCore.gyp/JavaScriptCore.gyp: + * wtf/CurrentTime.cpp: + +2009-10-27 Peter Varga <pvarga@inf.u-szeged.hu> + + Rubber-stamped by Tor Arne Vestbø. + + Fix typo in RegexInterpreter.cpp and RegexJIT.cpp alterantive to + alternative. + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::ByteCompiler::alternativeBodyDisjunction): + (JSC::Yarr::ByteCompiler::alternativeDisjunction): + (JSC::Yarr::ByteCompiler::emitDisjunction): + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateDisjunction): + +2009-10-26 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + Make .rc files compile on Windows without depending on MFC headers + https://bugs.webkit.org/show_bug.cgi?id=30750 + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: Use + winresrc.h because it exists even when MFC is not installed, and is + all that's needed here. + +2009-10-26 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + The thunkReturnAddress is on JITStackFrame on ARM JIT as well + https://bugs.webkit.org/show_bug.cgi?id=30782 + + Move the thunkReturnAddress from top of the stack into the JITStackFrame + structure. This is a requirement for JSValue32_64 support on ARM. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::ret): Return with link register + (JSC::MacroAssemblerARM::prepareCall): Store the return address in link register + * jit/JIT.h: Remove unused ctiReturnRegister + * jit/JITInlineMethods.h: Same as ARMv7 + (JSC::JIT::restoreArgumentReference): Ditto. + (JSC::JIT::restoreArgumentReferenceForTrampoline): Ditto. + * jit/JITOpcodes.cpp: Remove ctiReturnRegister related instruction + * jit/JITStubs.cpp: Store thunkReturnAddress on JITStackFrame. Use + small trampoline functions which handle return addresses for each + CTI_STUB_FUNCTION. + * jit/JITStubs.h: Store thunkReturnAddress on JITStackFrame + (JSC::JITStackFrame::returnAddressSlot): Return with the address of thunkReturnAddress + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): Remove the unnecessary instruction + +2009-10-26 Steve Block <steveblock@google.com> + + Reviewed by Darin Adler. + + Adds ability to disable ReadWriteLock on platforms (eg Android) that use pthreads but do not support pthread_rwlock. + https://bugs.webkit.org/show_bug.cgi?id=30713 + + * wtf/Platform.h: Modified. Defines HAVE_PTHREAD_RWLOCK for all platforms currently using pthreads. + * wtf/Threading.h: Modified. Use pthread_rwlock_t only when HAVE_PTHREAD_RWLOCK is defined. + * wtf/ThreadingPthreads.cpp: Modified. Build ReadWriteLock methods only when HAVE_PTHREAD_RWLOCK is defined. + +2009-10-24 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Holger Freyther. + + [Qt] [Symbian] Set the capability and memory required to run QtWebKit for Symbian + https://bugs.webkit.org/show_bug.cgi?id=30476 + + Assign ReadUserData WriteUserData NetworkServices Symbian capabilities + to jsc.exe. + + * jsc.pro: + +2009-10-23 Steve Block <steveblock@google.com> + + Reviewed by Dmitry Titov. + + Fixes a leak in createThreadInternal on Android. + https://bugs.webkit.org/show_bug.cgi?id=30698 + + * wtf/ThreadingPthreads.cpp: Modified. + (WTF::createThreadInternal): Avoid leaking a ThreadData object on failure. + +2009-10-22 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Alexey Proskuryakov. + + Fixed ASSERT when opening Safari's Caches window while the Web Inspector + is open. + + * runtime/Collector.cpp: + (JSC::typeName): Added two new types to the type name list in the Collector. + These types have been around for a while, but nobody remembered to consider them here. + + * runtime/JSCell.h: + (JSC::JSCell::isPropertyNameIterator): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::isPropertyNameIterator): Give the Collector + a way to tell if a cell is a JSPropertyNameIterator. + +2009-10-22 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Jon Honeycutt. + + https://bugs.webkit.org/show_bug.cgi?id=30686 + Remove debug-specific def file. + Only Debug_All target uses JavaScriptCore_debug.dll naming, and since + that target is only used internally, maintaining two files just to + suppress a single link warning isn't worthwhile. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Removed. + +2009-10-21 Jon Honeycutt <jhoneycutt@apple.com> + + <rdar://problem/7270320> Screenshots of off-screen plug-ins are blank + <rdar://problem/7270314> After halting a transparent PluginView on + Windows, the transparency is applied twice + + Reviewed by Dan Bernstein. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + Export WTF::deleteOwnedPtr(HDC). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + Ditto. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: updated variable name. + + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Mark Rowe. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): Slightly tweaked this #ifdef to match the + size of a JSValue because m_jsStrings is an array of JSValues. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Mark Rowe. + + Fixed a 64-bit regression caused by the fix for + https://bugs.webkit.org/show_bug.cgi?id=30570. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): Use TimesEight stepping on 64-bit, since + 64-bit pointers are eight bytes long. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Refactored DateInstance::msToGregorianDateTime so that a DateInstance's + caller doesn't need to supply the DateInstance's own internal value to + the DateInstance. + + * runtime/DateInstance.cpp: + (JSC::DateInstance::getGregorianDateTime): Renamed from "msToGregorianDateTime". + + * runtime/DateInstance.h: + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToISOString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncToLocaleString): + (JSC::dateProtoFuncToLocaleDateString): + (JSC::dateProtoFuncToLocaleTimeString): + (JSC::dateProtoFuncGetTime): + (JSC::dateProtoFuncGetFullYear): + (JSC::dateProtoFuncGetUTCFullYear): + (JSC::dateProtoFuncToGMTString): + (JSC::dateProtoFuncGetMonth): + (JSC::dateProtoFuncGetUTCMonth): + (JSC::dateProtoFuncGetDate): + (JSC::dateProtoFuncGetUTCDate): + (JSC::dateProtoFuncGetDay): + (JSC::dateProtoFuncGetUTCDay): + (JSC::dateProtoFuncGetHours): + (JSC::dateProtoFuncGetUTCHours): + (JSC::dateProtoFuncGetMinutes): + (JSC::dateProtoFuncGetUTCMinutes): + (JSC::dateProtoFuncGetSeconds): + (JSC::dateProtoFuncGetUTCSeconds): + (JSC::dateProtoFuncGetTimezoneOffset): + (JSC::setNewValueFromTimeArgs): + (JSC::setNewValueFromDateArgs): + (JSC::dateProtoFuncSetYear): + (JSC::dateProtoFuncGetYear): Also renamed "utc" to "outputIsUTC", for clarity. + +2009-10-20 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Geoffrey Garen. + + The op_next_pname should use 4 bytes addressing mode in case of JSValue32 + https://bugs.webkit.org/show_bug.cgi?id=30570 + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): + +2009-10-20 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Oliver Hunt. + + Move OverridesMarkChildren flag from DatePrototype to its parent class + https://bugs.webkit.org/show_bug.cgi?id=30372 + + * runtime/DateInstance.h: + (JSC::DateInstance::createStructure): + * runtime/DatePrototype.h: + +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some put_by_id_transition code generation. + https://bugs.webkit.org/show_bug.cgi?id=30539 + + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::testPrototype): + (JSC::JIT::privateCompilePutByIdTransition): No need to do object type + checks or read Structures and prototypes from objects: they're all known + constants at compile time. + +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added a private API for getting a global context from a context, for + clients who want to preserve a context for a later callback. + + * API/APICast.h: + (toGlobalRef): Added an ASSERT, since this function is used more often + than before. + + * API/JSContextRef.cpp: + * API/JSContextRefPrivate.h: Added. The new API. + + * API/tests/testapi.c: + (print_callAsFunction): + (main): Test the new API. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: Build and export the new API. + +2009-10-17 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some instanceof code generation. + https://bugs.webkit.org/show_bug.cgi?id=30488 + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): No need to do object type checks - + cell type checks and ImplementsDefaultHasIntance checks implicitly + supersede object type checks. + +2009-10-18 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Darin Adler. + + Use _stricmp and _strnicmp instead of deprecated stricmp and strnicmp. + https://bugs.webkit.org/show_bug.cgi?id=30474 + + stricmp and strnicmp are deprecated beginning in Visual + C++ 2005. Use _stricmp and _strnicmp instead in StringExtras.h. + + * wtf/StringExtras.h: + (strncasecmp): + (strcasecmp): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: apparently we shouldn't export those symbols? + + * JavaScriptCore.exp: + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: export some symbols. + + * JavaScriptCore.exp: + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + structure typeinfo flags should be inherited. + https://bugs.webkit.org/show_bug.cgi?id=30468 + + Add StructureFlag constant to the various JSC classes and use + it for the TypeInfo construction. This allows us to simply + accumulate flags by basing each classes StructureInfo on its parents. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSByteArray.h: + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fast for-in enumeration: Cache JSPropertyNameIterator; cache JSStrings + in JSPropertyNameIterator; inline more code. + + 1.024x as fast on SunSpider (fasta: 1.43x as fast). + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetPropertyNames): + (JSC::BytecodeGenerator::emitNextPropertyName): + * bytecompiler/BytecodeGenerator.h: Added a few extra operands to + op_get_pnames and op_next_pname so that we can track iteration state + in the register file instead of in the JSPropertyNameIterator. (To be + cacheable, the JSPropertyNameIterator must be stateless.) + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::Interpreter::privateExecute): Updated for in-RegisterFile + iteration state tracking. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_pnames): Updated for in-RegisterFile + iteration state tracking. + + (JSC::JIT::emit_op_next_pname): Inlined code generation for op_next_pname. + + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): Added has_property and to_object stubs. Removed op_next_pname + stub, since has_property is all we need anymore. + + * parser/Nodes.cpp: + (JSC::ForInNode::emitBytecode): Updated for in-RegisterFile + iteration state tracking. + + * runtime/JSCell.h: + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): Don't do caching at this layer + anymore, since we don't create a JSPropertyNameIterator at this layer. + + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): Do do caching at this layer. + (JSC::JSPropertyNameIterator::get): Updated for in-RegisterFile + iteration state tracking. + (JSC::JSPropertyNameIterator::markChildren): Mark our JSStrings. + + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::size): + (JSC::JSPropertyNameIterator::setCachedStructure): + (JSC::JSPropertyNameIterator::cachedStructure): + (JSC::JSPropertyNameIterator::setCachedPrototypeChain): + (JSC::JSPropertyNameIterator::cachedPrototypeChain): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + (JSC::Structure::setEnumerationCache): Don't store iteration state in + a JSPropertyNameIterator. Do cache a JSPropertyNameIterator in a + Structure. + + * runtime/JSValue.h: + (JSC::asCell): + * runtime/MarkStack.h: Make those mischievous #include gods happy. + + * runtime/ObjectConstructor.cpp: + + * runtime/Operations.h: + (JSC::normalizePrototypeChain): Renamed countPrototypeChainEntriesAndCheckForProxies + to normalizePrototypeChain, since it changes dictionary prototypes to + non-dictionary objects. + + * runtime/PropertyNameArray.cpp: + (JSC::PropertyNameArray::add): + * runtime/PropertyNameArray.h: + (JSC::PropertyNameArrayData::PropertyNameArrayData): + (JSC::PropertyNameArray::data): + (JSC::PropertyNameArray::size): + (JSC::PropertyNameArray::begin): + (JSC::PropertyNameArray::end): Simplified some code here to help with + current and future refactoring. + + * runtime/Protect.h: + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::removePropertyWithoutTransition): No need to clear + the enumeration cache with adding / removing properties without + transition. It is an error to add / remove properties without transition + once an object has been observed, and we can ASSERT to catch that. + + * runtime/Structure.h: + (JSC::Structure::enumerationCache): Changed the enumeration cache to + hold a JSPropertyNameIterator. + + * runtime/StructureChain.cpp: + * runtime/StructureChain.h: + (JSC::StructureChain::head): Removed StructureChain::isCacheable because + it was wrong-headed in two ways: (1) It gave up when a prototype was a + dictionary, but instead we want un-dictionary heavily accessed + prototypes; (2) It folded a test for hasDefaultGetPropertyNames() into + a generic test for "cacheable-ness", but hasDefaultGetPropertyNames() + is only releavant to for-in caching. + +2009-10-16 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Adam Roben. + + Add a Debug_All configuration to build entire stack as debug. + Change Debug_Internal to: + - stop using _debug suffix for all WebKit/Safari binaries + - not use _debug as a DLL naming suffix + - use non-debug C runtime lib. + + * JavaScriptCore.vcproj/JavaScriptCore.make: Debug build in makefile should build Debug_All. + * JavaScriptCore.vcproj/JavaScriptCore.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Renamed single configuration from "Release" to "all". + * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/jsc/jsc.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add Debug_All configuration. + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Last part -- replace HasDefaultGetPropertyNames with OverridesGetPropertyNames + flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetPropertyNames): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-10-16 Kevin Ollivier <kevino@theolliviers.com> + + wxMSW build fix, we can't use the simple hash there because the PlatformModuleVersion + structure differs. + + * wtf/Platform.h: + +2009-10-16 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement ExecutableAllocator for Symbian + https://bugs.webkit.org/show_bug.cgi?id=29946 + + Tested with YARR JIT enabled for Symbian; + This patch does not (yet) enable YARR JIT by default. + + * JavaScriptCore.pri: + * jit/ExecutableAllocator.h: + * jit/ExecutableAllocatorSymbian.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + +2009-10-15 Oliver Hunt <oliver@apple.com> + + Reviewed by Darin Adler. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 2 -- Reverse the TypeInfo HasDefaultMark flag to OverridesMarkChildren, etc + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GetterSetter.h: + (JSC::GetterSetter::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + (JSC::MarkStack::markChildren): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesMarkChildren): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 1. Reverse the HasStandardGetOwnPropertySlot flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + (JSC::JSCell::fastGetOwnPropertySlot): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetOwnPropertySlot): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> +2009-10-14 Darin Adler <darin@apple.com> + + Additions so fix for https://bugs.webkit.org/show_bug.cgi?id=18994 + can build on Windows. + + * wtf/MathExtras.h: Added llround and llroundf for Windows. + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Set ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH for plugins while we're still building stubs. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + Refactor ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + https://bugs.webkit.org/show_bug.cgi?id=30278 + + Move the definition of ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + from the make system into common code. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + ARM compiler does not understand reinterpret_cast<void*> + https://bugs.webkit.org/show_bug.cgi?id=29034 + + Change reinterpret_cast<void*> to regular C style (void*) cast + for the ARM RVCT compiler. + + * assembler/MacroAssemblerCodeRef.h: + (JSC::FunctionPtr::FunctionPtr): + * jit/JITOpcodes.cpp: Cast to FunctionPtr first + instead of directly casting to reinterpret_cast + * jit/JITStubCall.h: Ditto + change the type of m_stub + from void* to FunctionPtr. + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::call): + * jit/JITStubs.cpp: Ditto. + (JSC::DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)): + +2009-10-11 Oliver Hunt <oliver@apple.com> + + Re-enable the JIT. + + * wtf/Platform.h: + +2009-10-10 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Support for String.trim(), String.trimLeft() and String.trimRight() methods + https://bugs.webkit.org/show_bug.cgi?id=26590 + + Implement trim, trimLeft, and trimRight + + * runtime/StringPrototype.cpp: + (JSC::isTrimWhitespace): + Our normal string whitespace function does not include U+200B which + is needed for compatibility with mozilla's implementation of trim. + U+200B does not appear to be expected according to spec, however I am + choosing to be lax, and match mozilla behavior so have added this + exception. + (JSC::trimString): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Eliminated some legacy bytecode weirdness. + + Use vPC[x] subscripting instead of ++vPC to access instruction operands. + This is simpler, and often more efficient. + + To support this, and to remove use of hard-coded offsets in bytecode and + JIT code generation and dumping, calculate jump offsets from the beginning + of an instruction, rather than the middle or end. + + Also, use OPCODE_LENGTH instead of hard-coded constants for the sizes of + opcodes. + + SunSpider reports no change in JIT mode, and a 1.01x speedup in Interpreter + mode. + + * bytecode/CodeBlock.cpp: + (JSC::printConditionalJump): + (JSC::CodeBlock::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitJump): + (JSC::BytecodeGenerator::emitJumpIfTrue): + (JSC::BytecodeGenerator::emitJumpIfFalse): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply): + (JSC::BytecodeGenerator::emitComplexJumpScopes): + (JSC::BytecodeGenerator::emitJumpScopes): + (JSC::BytecodeGenerator::emitNextPropertyName): + (JSC::BytecodeGenerator::emitCatch): + (JSC::BytecodeGenerator::emitJumpSubroutine): + (JSC::prepareJumpTableForImmediateSwitch): + (JSC::prepareJumpTableForCharacterSwitch): + (JSC::prepareJumpTableForStringSwitch): + (JSC::BytecodeGenerator::endSwitch): + * bytecompiler/Label.h: + (JSC::Label::setLocation): + (JSC::Label::bind): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolve): + (JSC::Interpreter::resolveSkip): + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::resolveBase): + (JSC::Interpreter::resolveBaseAndProperty): + (JSC::Interpreter::createExceptionScope): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + (JSC::JIT::emitBinaryDoubleOp): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_loop): + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emitSlow_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emitSlow_op_loop_if_lesseq): + (JSC::JIT::emit_op_loop_if_true): + (JSC::JIT::emitSlow_op_loop_if_true): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emitSlow_op_jfalse): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emitSlow_op_jtrue): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_jsr): + (JSC::JIT::emit_op_next_pname): + (JSC::JIT::emit_op_jmp_scopes): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Migrated some code that didn't belong out of Structure. + + SunSpider says maybe 1.03x faster. + + * runtime/JSCell.h: Nixed Structure::markAggregate, and made marking of + a Structure's prototype the direct responsility of the object using it. + (Giving Structure a mark function was misleading because it implied that + all live structures get marked during GC, when they don't.) + + * runtime/JSGlobalObject.cpp: + (JSC::markIfNeeded): + (JSC::JSGlobalObject::markChildren): Added code to mark prototypes stored + on the global object. Maybe this wasn't necessary, but now we don't have + to wonder. + + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::getEnumerableNamesFromClassInfoTable): + * runtime/JSObject.h: + (JSC::JSObject::markChildrenDirect): + * runtime/PropertyNameArray.h: + * runtime/Structure.cpp: + * runtime/Structure.h: + (JSC::Structure::setEnumerationCache): + (JSC::Structure::enumerationCache): Moved property name gathering code + from Structure to JSObject because having a Structure iterate its JSObject + was a layering violation. A JSObject is implemented using a Structure; not + the other way around. + +2009-10-09 Mark Rowe <mrowe@apple.com> + + Attempt to fix the GTK release build. + + * GNUmakefile.am: Include Grammar.cpp in release builds now that + AllInOneFile.cpp is gone. + +2009-10-09 Gabor Loki <loki@inf.u-szeged.hu> + + Rubber-stamped by Eric Seidel. + + Add ARM JIT support for Gtk port (disabled by default) + https://bugs.webkit.org/show_bug.cgi?id=30228 + + * GNUmakefile.am: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: added a few more variable initializations. + + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncSearch): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Qt build fix: added missing #include. + + * jsc.cpp: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: initialize variable whose initialization the compiler + can't otherwise figure out. + + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: updated exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: fixed file name case. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + At long last, I pronounce the death of AllInOneFile.cpp. + + SunSpider reports a 1.01x speedup. + + * AllInOneFile.cpp: Removed. + * GNUmakefile.am: + * JavaScriptCore.exp: + * JavaScriptCore.gypi: + * JavaScriptCore.xcodeproj/project.pbxproj: Added missing project files + to compilation stages. + + * parser/Grammar.y: + * parser/Lexer.cpp: + * parser/Lexer.h: + (JSC::jscyylex): + * runtime/ArrayConstructor.cpp: + (JSC::constructArrayWithSizeQuirk): + * runtime/Collector.h: + * runtime/JSCell.cpp: + (JSC::JSCell::operator new): + * runtime/JSCell.h: + (JSC::JSCell::operator new): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::operator new): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::operator new): + * runtime/JSString.cpp: + * runtime/JSString.h: + (JSC::jsString): + (JSC::jsSubstring): + (JSC::jsOwnedString): + * runtime/RegExpConstructor.cpp: + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructorPrivate::RegExpConstructorPrivate): + (JSC::RegExpConstructorPrivate::lastOvector): + (JSC::RegExpConstructorPrivate::tempOvector): + (JSC::RegExpConstructorPrivate::changeLastOvector): + (JSC::RegExpConstructor::performMatch): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncMatch): + * yarr/RegexJIT.cpp: + * yarr/RegexJIT.h: + (JSC::Yarr::executeRegex): Inlined a few things that Shark said + were hot, on the presumption that AllInOneFile.cpp used to inline them + automatically. + +2009-10-08 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Fix for JIT'ed op_call instructions (evals, constructs, etc.) + when !ENABLE(JIT_OPTIMIZE_CALL) && USE(JSVALUE32_64) + + https://bugs.webkit.org/show_bug.cgi?id=30201 + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + +2009-10-07 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: removed no longer exported symbol. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-07 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fixed <rdar://problem/5751979> Database code takes JSLock on secondary + thread, permanently slowing down JavaScript + + Removed the optional lock from Heap::protect, Heap::unprotect, and friends, + since WebCore no longer uses it. + + * JavaScriptCore.exp: + * runtime/Collector.cpp: + (JSC::Heap::protect): + (JSC::Heap::unprotect): + (JSC::Heap::markProtectedObjects): + (JSC::Heap::protectedGlobalObjectCount): + (JSC::Heap::protectedObjectCount): + (JSC::Heap::protectedObjectTypeCounts): + * runtime/Collector.h: + +2009-10-07 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's IdentifierArena + https://bugs.webkit.org/show_bug.cgi?id=30158 + + Inherits IdentifierArena class from FastAllocBase because it has been + instantiated by 'new' in JavaScriptCore/parser/ParserArena.cpp:36. + + * parser/ParserArena.h: + +2009-10-07 Adam Roben <aroben@apple.com> + + Export DateInstance::info in a way that works on Windows + + Fixes <http://webkit.org/b/30171> + fast/dom/Window/window-postmessage-clone.html fails on Windows + + Reviewed by Anders Carlsson. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + Removed the export of DateInstance::info from here. + + * runtime/DateInstance.h: Use JS_EXPORTDATA to export + DateInstance::info, which is the required way of exporting data on + Windows. + +2009-10-07 Jørgen Lind <jorgen.lind@nokia.com> + + Reviewed by Simon Hausmann. + + When enabling or disabling the JIT through .qmake.cache, make sure + to also toggle ENABLE_YARR_JIT. + + * JavaScriptCore.pri: + +2009-10-06 Priit Laes <plaes@plaes.org> + + Reviewed by Gavin Barraclough. + + Linking fails with "relocation R_X86_64_PC32 against symbol + `cti_vm_throw'" + https://bugs.webkit.org/show_bug.cgi?id=28422 + + * jit/JITStubs.cpp: + Mark cti_vm_throw symbol as PLT-indirect symbol, so it doesn't end up + in text segment causing relocation errors on amd64 architecture. + Introduced new define SYMBOL_STRING_RELOCATION for such symbols. + +2009-10-06 Oliver Hunt <oliver@apple.com> + + Windows linking fix + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-06 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (build fix). + + Windows build fix. + + * runtime/DateInstance.cpp: + +2009-10-05 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + It should be possible to post (clone) built-in JS objects to Workers + https://bugs.webkit.org/show_bug.cgi?id=22878 + + Expose helpers to throw correct exceptions during object graph walk + used for cloning and add a helper function to create Date instances + without going through the JS Date constructor function. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + * runtime/DateInstance.h: + * runtime/ExceptionHelpers.cpp: + (JSC::createTypeError): + * runtime/ExceptionHelpers.h: + +2009-10-06 David Levin <levin@chromium.org> + + Reviewed by Oliver Hunt. + + StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer. + https://bugs.webkit.org/show_bug.cgi?id=30095 + + * wtf/CrossThreadRefCounted.h: + Removed an unused function and assert improvement. + (WTF::CrossThreadRefCounted::isOwnedByCurrentThread): Moved out common code from asserts. + (WTF::CrossThreadRefCounted::ref): Changed assert to use the common method. + (WTF::CrossThreadRefCounted::deref): Changed assert to use the common method. + (WTF::CrossThreadRefCounted::crossThreadCopy): Since this includes a potentially + non-threadsafe operation, add an assert that the class is owned by the current thread. + +2009-10-05 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Add Symbian files to the list of excludes. + + * wscript: + +2009-10-05 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Remove precompiled header from JavaScriptCore compilation to + prevent qmake warning during autonomous compilation. + https://bugs.webkit.org/show_bug.cgi?id=30069 + + * JavaScriptCore.pro: + +2009-10-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Removed the concept of a "fast access cutoff" in arrays, because it + punished some patterns of array access too much, and made things too + complex for inlining in some cases. + + 1.3% speedup on SunSpider. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITStubs.cpp: + * jit/JITStubs.h: + (JSC::): Check m_vectorLength instead of m_fastAccessCutoff when + getting / putting from / to an array. Inline putting past the end of + the array. + + * runtime/JSArray.cpp: + (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::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::canGetIndex): + (JSC::JSArray::canSetIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::markChildrenDirect): Removed m_fastAccessCutoff, and + replaced with checks for JSValue() to detect reads and writes from / to + uninitialized parts of the array. + +2009-10-02 Jonni Rainisto <jonni.rainisto@nokia.com> + + Reviewed by Darin Adler. + + Math.random() gives too low values on Win32 when _CRT_RAND_S is not defined + https://bugs.webkit.org/show_bug.cgi?id=29956 + + * wtf/RandomNumber.cpp: + (WTF::randomNumber): Added PLATFORM(WIN_OS) to handle 15bit rand() + +2009-10-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Take one branch instead of two to test for JSValue(). + + 1.1% SunSpider speedup. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emit_op_create_arguments): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + + * runtime/JSValue.cpp: + (JSC::JSValue::description): Added support for dumping the new empty value, + and deleted values, in debug builds. + + * runtime/JSValue.h: + (JSC::JSValue::JSValue()): Construct JSValue() with the empty value tag. + + (JSC::JSValue::JSValue(JSCell*)): Convert null pointer to the empty value + tag, to avoid having two different c++ versions of null / empty. + + (JSC::JSValue::operator bool): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + +2009-10-02 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Mark Rowe. + + <https://bugs.webkit.org/show_bug.cgi?id=29989> + Safari version number shouldn't be exposed in WebKit code + + For a WebKit version of 532.3.4: + Product version is: 5.32.3.4 (was 4.0.3.0) + File version is: 5.32.3.4 (was 4.532.3.4) + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: + +2009-10-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Rubber-stamped by Simon Hausmann. + + Fix the Qt on Mac OS X build. + + * wtf/FastMalloc.cpp: + +2009-10-02 Jørgen Lind <jorgen.lind@nokia.com> + + Reviewed by Simon Hausmann. + + Allow enabling and disabling of the JIT through a qmake variable. + + Qt's configure may set this variable through .qmake.cache if a + commandline option is given and/or the compile test for hwcap.h + failed/succeeded. + + * JavaScriptCore.pri: + +2009-10-01 Mark Rowe <mrowe@apple.com> + + Fix the Tiger build. Don't unconditionally enable 3D canvas as it is not supported on Tiger. + + * Configurations/FeatureDefines.xcconfig: + +2009-10-01 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=29187 + + Don't inline ~ListRefPtr() to work around winscw compiler forward declaration + bug regarding templated classes. + + The compiler bug is reported at: + https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812 + + The change will be reverted when the above bug is fixed in winscw compiler. + + * wtf/ListRefPtr.h: + (WTF::::~ListRefPtr): + +2009-10-01 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Allow custom memory allocation control for the whole JavaScriptCore + https://bugs.webkit.org/show_bug.cgi?id=27029 + + Since in JavaScriptCore almost every class which has been instantiated by operator new is + inherited from FastAllocBase (bug #20422), we disable customizing global operator new for the Qt-port + when USE_SYSTEM_MALLOC=0. + + Add #include <unistd.h> to FastMalloc.cpp because it's used by TCMalloc_PageHeap::scavengerThread(). + (It's needed for the functionality of TCmalloc.) + + Add TCSystemAlloc.cpp to JavaScriptCore.pri if USE_SYSTEM_MALLOC is disabled. + + * JavaScriptCore.pri: + * wtf/FastMalloc.cpp: + (WTF::sleep): + * wtf/FastMalloc.h: + +2009-09-30 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by George Staikos. + + Defines two pseudo-platforms for ARM and Thumb-2 instruction set. + https://bugs.webkit.org/show_bug.cgi?id=29122 + + Introduces WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 + macros on ARM platforms. The PLATFORM(ARM_THUMB2) should be used + when Thumb-2 instruction set is the required target. The + PLATFORM(ARM_TRADITIONAL) is for generic ARM instruction set. In + case where the code is common the PLATFORM(ARM) have to be used. + + Modified by George Wright <gwright@rim.com> to correctly work + with the RVCT-defined __TARGET_ARCH_ARM and __TARGET_ARCH_THUMB + compiler macros, as well as adding readability changes. + + * wtf/Platform.h: + +2009-09-30 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Devirtualise array toString conversion + + Tweak the implementation of Array.prototype.toString to have a fast path + when acting on a true JSArray. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + +2009-09-30 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Geoffrey Garen. + Buildfix for platforms using JSVALUE32. https://bugs.webkit.org/show_bug.cgi?id=29915 After http://trac.webkit.org/changeset/48905 the build broke in JSVALUE32 case. + Also removed unreachable code. * jit/JITArithmetic.cpp: (JSC::JIT::emit_op_add): - Declaration of "OperandTypes types" moved before first use. - Typos fixed: dst modified to result, regT2 added. - - Unnecessary code removed. + - Unreachable code removed. (JSC::JIT::emitSlow_op_add): - Missing declaration of "OperandTypes types" added. diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi index 15a0c0f5fa..03c23c35c2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi @@ -1,7 +1,6 @@ { 'variables': { 'javascriptcore_files': [ - 'AllInOneFile.cpp', 'API/APICast.h', 'API/JavaScript.h', 'API/JavaScriptCore.h', @@ -19,6 +18,7 @@ 'API/JSClassRef.h', 'API/JSContextRef.cpp', 'API/JSContextRef.h', + 'API/JSContextRefPrivate.h', 'API/JSObjectRef.cpp', 'API/JSObjectRef.h', 'API/JSProfilerPrivate.cpp', @@ -194,6 +194,7 @@ 'runtime/DateConversion.h', 'runtime/DateInstance.cpp', 'runtime/DateInstance.h', + 'runtime/DateInstanceCache.h', 'runtime/DatePrototype.cpp', 'runtime/DatePrototype.h', 'runtime/Error.cpp', diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri index 2b08980b4b..bb531e5bee 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri @@ -39,10 +39,12 @@ win32-* { contains(JAVASCRIPTCORE_JIT,yes) { DEFINES+=ENABLE_JIT=1 DEFINES+=ENABLE_YARR_JIT=1 + DEFINES+=ENABLE_YARR=1 } contains(JAVASCRIPTCORE_JIT,no) { DEFINES+=ENABLE_JIT=0 DEFINES+=ENABLE_YARR_JIT=0 + DEFINES+=ENABLE_YARR=0 } # In debug mode JIT disabled until crash fixed @@ -52,14 +54,15 @@ win32-* { # Rules when JIT enabled (not disabled) !contains(DEFINES, ENABLE_JIT=0) { - linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) { + linux*-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) { QMAKE_CXXFLAGS += -fno-stack-protector QMAKE_CFLAGS += -fno-stack-protector } } wince* { - SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.cpp + INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat + SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c DEFINES += WINCEBASIC } @@ -137,7 +140,8 @@ SOURCES += \ interpreter/RegisterFile.cpp symbian { - SOURCES += runtime/MarkStackSymbian.cpp + SOURCES += jit/ExecutableAllocatorSymbian.cpp \ + runtime/MarkStackSymbian.cpp } else { win32-*|wince* { SOURCES += jit/ExecutableAllocatorWin.cpp \ @@ -148,6 +152,10 @@ symbian { } } +!contains(DEFINES, USE_SYSTEM_MALLOC) { + SOURCES += wtf/TCSystemAlloc.cpp +} + # AllInOneFile.cpp helps gcc analize and optimize code # Other compilers may be able to do this at link time SOURCES += \ diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro index 0cd2e1a9fc..a1affd4d6e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro @@ -16,7 +16,6 @@ CONFIG(QTDIR_build) { include($$QT_SOURCE_TREE/src/qbase.pri) INSTALLS = DESTDIR = $$OLDDESTDIR - PRECOMPILED_HEADER = $$PWD/../WebKit/qt/WebKit_pch.h DEFINES *= NDEBUG } diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h index 078de44748..02ce2e93a1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h @@ -407,6 +407,11 @@ register writeback class ARMv7Assembler { public: + ~ARMv7Assembler() + { + ASSERT(m_jumpsToLink.isEmpty()); + } + typedef ARMRegisters::RegisterID RegisterID; typedef ARMRegisters::FPRegisterID FPRegisterID; @@ -477,6 +482,17 @@ public: private: + struct LinkRecord { + LinkRecord(intptr_t from, intptr_t to) + : from(from) + , to(to) + { + } + + intptr_t from; + intptr_t to; + }; + // ARMv7, Appx-A.6.3 bool BadReg(RegisterID reg) { @@ -574,6 +590,7 @@ private: OP_SUB_SP_imm_T1 = 0xB080, OP_BKPT = 0xBE00, OP_IT = 0xBF00, + OP_NOP_T1 = 0xBF00, } OpcodeID; typedef enum { @@ -608,6 +625,7 @@ private: OP_MOV_imm_T3 = 0xF240, OP_SUB_imm_T4 = 0xF2A0, OP_MOVT = 0xF2C0, + OP_NOP_T2a = 0xF3AF, OP_LDRH_reg_T2 = 0xF830, OP_LDRH_imm_T3 = 0xF830, OP_STR_imm_T4 = 0xF840, @@ -626,6 +644,7 @@ private: typedef enum { OP_B_T4b = 0x9000, + OP_NOP_T2b = 0x8000, } OpcodeID2; struct FourFours { @@ -1481,6 +1500,15 @@ public: void* executableCopy(ExecutablePool* allocator) { void* copy = m_formatter.executableCopy(allocator); + + unsigned jumpCount = m_jumpsToLink.size(); + for (unsigned i = 0; i < jumpCount; ++i) { + uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].from); + uint16_t* target = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].to); + linkJumpAbsolute(location, target); + } + m_jumpsToLink.clear(); + ASSERT(copy); return copy; } @@ -1503,11 +1531,7 @@ public: { ASSERT(to.m_offset != -1); ASSERT(from.m_offset != -1); - - uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(m_formatter.data()) + from.m_offset); - intptr_t relative = to.m_offset - from.m_offset; - - linkWithOffset(location, relative); + m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset)); } static void linkJump(void* code, JmpSrc from, void* to) @@ -1515,9 +1539,7 @@ public: ASSERT(from.m_offset != -1); uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset); - intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(location); - - linkWithOffset(location, relative); + linkJumpAbsolute(location, to); } // bah, this mathod should really be static, since it is used by the LinkBuffer. @@ -1541,10 +1563,9 @@ public: ASSERT(!(reinterpret_cast<intptr_t>(from) & 1)); ASSERT(!(reinterpret_cast<intptr_t>(to) & 1)); - intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from); - linkWithOffset(reinterpret_cast<uint16_t*>(from), relative); + linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to); - ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 2, 2 * sizeof(uint16_t)); + ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t)); } static void relinkCall(void* from, void* to) @@ -1613,14 +1634,14 @@ private: static void setInt32(void* code, uint32_t value) { uint16_t* location = reinterpret_cast<uint16_t*>(code); + ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2)); - uint16_t lo16 = value; - uint16_t hi16 = value >> 16; - - spliceHi5(location - 4, lo16); - spliceLo11(location - 3, lo16); - spliceHi5(location - 2, hi16); - spliceLo11(location - 1, hi16); + ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value)); + ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value >> 16)); + location[-4] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); + location[-3] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-3] >> 8) & 0xf, lo16); + location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); + location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16); ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t)); } @@ -1630,41 +1651,89 @@ private: setInt32(code, reinterpret_cast<uint32_t>(value)); } - // Linking & patching: - // This method assumes that the JmpSrc being linked is a T4 b instruction. - static void linkWithOffset(uint16_t* instruction, intptr_t relative) - { - // Currently branches > 16m = mostly deathy. - if (((relative << 7) >> 7) != relative) { - // FIXME: This CRASH means we cannot turn the JIT on by default on arm-v7. - fprintf(stderr, "Error: Cannot link T4b.\n"); - CRASH(); - } - - // ARM encoding for the top two bits below the sign bit is 'peculiar'. - if (relative >= 0) - relative ^= 0xC00000; + static bool isB(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xf800) == OP_B_T4a) && ((instruction[1] & 0xd000) == OP_B_T4b); + } + + static bool isBX(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return (instruction[0] & 0xff87) == OP_BX; + } - // All branch offsets should be an even distance. - ASSERT(!(relative & 1)); + static bool isMOV_imm_T3(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xFBF0) == OP_MOV_imm_T3) && ((instruction[1] & 0x8000) == 0); + } - int word1 = ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); - int word2 = ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); + static bool isMOVT(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xFBF0) == OP_MOVT) && ((instruction[1] & 0x8000) == 0); + } - instruction[-2] = OP_B_T4a | word1; - instruction[-1] = OP_B_T4b | word2; + static bool isNOP_T1(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return instruction[0] == OP_NOP_T1; } - // These functions can be used to splice 16-bit immediates back into previously generated instructions. - static void spliceHi5(uint16_t* where, uint16_t what) + static bool isNOP_T2(void* address) { - uint16_t pattern = (what >> 12) | ((what & 0x0800) >> 1); - *where = (*where & 0xFBF0) | pattern; + uint16_t* instruction = static_cast<uint16_t*>(address); + return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b); } - static void spliceLo11(uint16_t* where, uint16_t what) + + static void linkJumpAbsolute(uint16_t* instruction, void* target) { - uint16_t pattern = ((what & 0x0700) << 4) | (what & 0x00FF); - *where = (*where & 0x8F00) | pattern; + // FIMXE: this should be up in the MacroAssembler layer. :-( + const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; + + ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); + ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); + + ASSERT( (isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) + || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) ); + + intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); + if (((relative << 7) >> 7) == relative) { + // ARM encoding for the top two bits below the sign bit is 'peculiar'. + if (relative >= 0) + relative ^= 0xC00000; + + // All branch offsets should be an even distance. + ASSERT(!(relative & 1)); + // There may be a better way to fix this, but right now put the NOPs first, since in the + // case of an conditional branch this will be coming after an ITTT predicating *three* + // instructions! Looking backwards to modify the ITTT to an IT is not easy, due to + // variable wdith encoding - the previous instruction might *look* like an ITTT but + // actually be the second half of a 2-word op. + instruction[-5] = OP_NOP_T1; + instruction[-4] = OP_NOP_T2a; + instruction[-3] = OP_NOP_T2b; + instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); + instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); + } else { + ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); + ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); + instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); + instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16); + instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); + instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); + instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); + } + } + + static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm) + { + return op | (imm.m_value.i << 10) | imm.m_value.imm4; + } + static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm) + { + return (imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8; } class ARMInstructionFormatter { @@ -1723,8 +1792,11 @@ private: void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm) { - m_buffer.putShort(op | (imm.m_value.i << 10) | imm4); - m_buffer.putShort((imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8); + ARMThumbImmediate newImm = imm; + newImm.m_value.imm4 = imm4; + + m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst(op, newImm)); + m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, newImm)); } void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm) @@ -1749,6 +1821,8 @@ private: private: AssemblerBuffer m_buffer; } m_formatter; + + Vector<LinkRecord> m_jumpsToLink; }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h index aa8cbb036a..7a72b0698f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -65,6 +65,7 @@ public: }; static const RegisterID stackPointerRegister = ARMRegisters::sp; + static const RegisterID linkRegister = ARMRegisters::lr; static const Scale ScalePtr = TimesFour; @@ -530,7 +531,7 @@ public: void ret() { - pop(ARMRegisters::pc); + m_assembler.mov_r(ARMRegisters::pc, linkRegister); } void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) @@ -746,11 +747,9 @@ protected: void prepareCall() { - ensureSpace(3 * sizeof(ARMWord), sizeof(ARMWord)); + ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord)); - // S0 might be used for parameter passing - m_assembler.add_r(ARMRegisters::S1, ARMRegisters::pc, ARMAssembler::OP2_IMM | 0x4); - m_assembler.push_r(ARMRegisters::S1); + m_assembler.mov_r(linkRegister, ARMRegisters::pc); } void call32(RegisterID base, int32_t offset) diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARMv7.h index a549604ff0..c4795172d2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -990,13 +990,15 @@ public: protected: ARMv7Assembler::JmpSrc makeJump() { - return m_assembler.b(); + moveFixedWidthEncoding(Imm32(0), dataTempRegister); + return m_assembler.bx(dataTempRegister); } ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond) { - m_assembler.it(cond); - return m_assembler.b(); + m_assembler.it(cond, true, true); + moveFixedWidthEncoding(Imm32(0), dataTempRegister); + return m_assembler.bx(dataTempRegister); } ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); } ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 568260a4f9..3681af8a8c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -69,7 +69,13 @@ public: template<typename FunctionType> explicit FunctionPtr(FunctionType* value) +#if COMPILER(RVCT) + // RVTC compiler needs C-style cast as it fails with the following error + // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers + : m_value((void*)(value)) +#else : m_value(reinterpret_cast<void*>(value)) +#endif { ASSERT_VALID_CODE_POINTER(m_value); } diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp index 6bac9b94c4..c9159341dc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp @@ -135,11 +135,6 @@ NEVER_INLINE static const char* debugHookName(int debugHookID) return ""; } -static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset) -{ - return it - begin + offset; -} - static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op) { int r0 = (++it)->u.operand; @@ -156,11 +151,11 @@ static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); } -static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op) +static void printConditionalJump(const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) { int r0 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, location + offset); } static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op) @@ -829,6 +824,16 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); break; } + case op_get_by_pname: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int r2 = (++it)->u.operand; + int r3 = (++it)->u.operand; + int r4 = (++it)->u.operand; + int r5 = (++it)->u.operand; + printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), registerName(r4).c_str(), registerName(r5).c_str()); + break; + } case op_put_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; @@ -852,12 +857,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_loop: { int offset = (++it)->u.operand; - printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { @@ -884,56 +889,56 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_less: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_lesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_switch_imm: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_char: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_string: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_new_func: { @@ -1020,16 +1025,21 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& break; } case op_get_pnames: { - int r0 = (++it)->u.operand; - int r1 = (++it)->u.operand; - printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + int r0 = it[1].u.operand; + int r1 = it[2].u.operand; + int r2 = it[3].u.operand; + int r3 = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_get_pnames) - 1; break; } case op_next_pname: { - int dest = (++it)->u.operand; - int iter = (++it)->u.operand; - int offset = (++it)->u.operand; - printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset)); + int dest = it[1].u.operand; + int iter = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_next_pname) - 1; break; } case op_push_scope: { @@ -1051,7 +1061,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jmp_scopes: { int scopeDelta = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); break; } case op_catch: { @@ -1074,7 +1084,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jsr: { int retAddrDst = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, location + offset); break; } case op_sret: { diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h index c9196ce546..4facbef5b2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h @@ -113,6 +113,7 @@ namespace JSC { macro(op_put_by_id_generic, 8) \ macro(op_del_by_id, 4) \ macro(op_get_by_val, 4) \ + macro(op_get_by_pname, 7) \ macro(op_put_by_val, 4) \ macro(op_del_by_val, 4) \ macro(op_put_by_index, 4) \ @@ -152,8 +153,8 @@ namespace JSC { macro(op_strcat, 4) \ macro(op_to_primitive, 3) \ \ - macro(op_get_pnames, 3) \ - macro(op_next_pname, 4) \ + macro(op_get_pnames, 6) \ + macro(op_next_pname, 7) \ \ macro(op_push_scope, 2) \ macro(op_pop_scope, 1) \ diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 8951ce39f5..04dae15374 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -608,8 +608,9 @@ void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp() PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target) { + size_t begin = instructions().size(); emitOpcode(target->isForward() ? op_jmp : op_loop); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -624,10 +625,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_less); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) { @@ -639,10 +642,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_lesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { @@ -653,9 +658,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null && target->isForward()) { @@ -666,16 +673,20 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); + emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -692,10 +703,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnless); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq) { @@ -707,10 +720,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnlesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_not) { @@ -721,9 +736,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jtrue); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null) { @@ -734,9 +751,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null) { @@ -747,34 +766,41 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); emitOpcode(op_jfalse); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->callFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->applyFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -1255,6 +1281,19 @@ RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property) { + for (size_t i = m_forInContextStack.size(); i > 0; i--) { + ForInContext& context = m_forInContextStack[i - 1]; + if (context.propertyRegister == property) { + emitOpcode(op_get_by_pname); + instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(property->index()); + instructions().append(context.expectedSubscriptRegister->index()); + instructions().append(context.iterRegister->index()); + instructions().append(context.indexRegister->index()); + return dst; + } + } emitOpcode(op_get_by_val); instructions().append(dst->index()); instructions().append(base->index()); @@ -1718,6 +1757,8 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro } if (nNormalScopes) { + size_t begin = instructions().size(); + // We need to remove a number of dynamic scopes to get to the next // finally block emitOpcode(op_jmp_scopes); @@ -1726,14 +1767,14 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro // If topScope == bottomScope then there isn't actually a finally block // left to emit, so make the jmp_scopes jump directly to the target label if (topScope == bottomScope) { - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } // Otherwise we just use jmp_scopes to pop a group of scopes and go // to the next instruction RefPtr<Label> nextInsn = newLabel(); - instructions().append(nextInsn->offsetFrom(instructions().size())); + instructions().append(nextInsn->bind(begin, instructions().size())); emitLabel(nextInsn.get()); } @@ -1758,27 +1799,47 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetSco if (m_finallyDepth) return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta); + size_t begin = instructions().size(); + emitOpcode(op_jmp_scopes); instructions().append(scopeDelta); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } -RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target) +RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget) { + size_t begin = instructions().size(); + + emitOpcode(op_get_pnames); + instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); + instructions().append(breakTarget->bind(begin, instructions().size())); + return dst; +} + +RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target) +{ + size_t begin = instructions().size(); + emitOpcode(op_next_pname); instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); instructions().append(iter->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return dst; } RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end) { #if ENABLE(JIT) - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; #else - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; #endif m_codeBlock->addExceptionHandler(info); @@ -1798,9 +1859,11 @@ RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSV PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally) { + size_t begin = instructions().size(); + emitOpcode(op_jsr); instructions().append(retAddrDst->index()); - instructions().append(finally->offsetFrom(instructions().size())); + instructions().append(finally->bind(begin, instructions().size())); emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. return finally; } @@ -1870,7 +1933,7 @@ static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1896,7 +1959,7 @@ static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1910,7 +1973,7 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t ASSERT(nodes[i]->isString()); UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep(); OffsetLocation location; - location.branchOffset = labels[i]->offsetFrom(switchAddress); + location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3); jumpTable.offsetTable.add(clause, location); } } @@ -1921,23 +1984,23 @@ void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, E m_switchContextStack.removeLast(); if (switchInfo.switchType == SwitchInfo::SwitchImmediate) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable(); - prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable(); - prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else { ASSERT(switchInfo.switchType == SwitchInfo::SwitchString); instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable(); - prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes); + prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 1a83ce995c..4648fb57e6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -61,6 +61,13 @@ namespace JSC { FinallyContext finallyContext; }; + struct ForInContext { + RefPtr<RegisterID> expectedSubscriptRegister; + RefPtr<RegisterID> iterRegister; + RefPtr<RegisterID> indexRegister; + RefPtr<RegisterID> propertyRegister; + }; + class BytecodeGenerator : public FastAllocBase { public: typedef DeclarationStacks::VarStack VarStack; @@ -312,8 +319,8 @@ namespace JSC { PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*); void emitSubroutineReturn(RegisterID* retAddrSrc); - RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); } - RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target); + RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget); + RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target); RegisterID* emitCatch(RegisterID*, Label* start, Label* end); void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); } @@ -331,6 +338,17 @@ namespace JSC { void pushFinallyContext(Label* target, RegisterID* returnAddrDst); void popFinallyContext(); + void pushOptimisedForIn(RegisterID* expectedBase, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister) + { + ForInContext context = { expectedBase, iter, index, propertyRegister }; + m_forInContextStack.append(context); + } + + void popOptimisedForIn() + { + m_forInContextStack.removeLast(); + } + LabelScope* breakTarget(const Identifier&); LabelScope* continueTarget(const Identifier&); @@ -467,6 +485,7 @@ namespace JSC { Vector<ControlFlowContext> m_scopeContextStack; Vector<SwitchInfo> m_switchContextStack; + Vector<ForInContext> m_forInContextStack; int m_nextGlobalIndex; int m_nextParameterIndex; diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h index 0b3d038242..8cab1dbc00 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h @@ -51,19 +51,17 @@ namespace JSC { m_location = location; unsigned size = m_unresolvedJumps.size(); - for (unsigned i = 0; i < size; ++i) { - unsigned j = m_unresolvedJumps[i]; - m_codeBlock->instructions()[j].u.operand = m_location - j; - } + for (unsigned i = 0; i < size; ++i) + m_codeBlock->instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first; } - int offsetFrom(int location) const + int bind(int opcode, int offset) const { if (m_location == invalidLocation) { - m_unresolvedJumps.append(location); + m_unresolvedJumps.append(std::make_pair(opcode, offset)); return 0; } - return m_location - location; + return m_location - opcode; } void ref() { ++m_refCount; } @@ -77,7 +75,7 @@ namespace JSC { bool isForward() const { return m_location == invalidLocation; } private: - typedef Vector<int, 8> JumpVector; + typedef Vector<std::pair<int, int>, 8> JumpVector; static const unsigned invalidLocation = UINT_MAX; diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h index dd342656fa..63cf63558e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h @@ -51,9 +51,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | JSObject::StructureFlags; + private: JSActivation* m_activation; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp index 71451d6d97..4f78903844 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,159 +54,28 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 1 /* Substitute the variable and function names. */ -#define yyparse jscyyparse -#define yylex jscyylex -#define yyerror jscyyerror -#define yylval jscyylval -#define yychar jscyychar -#define yydebug jscyydebug -#define yynerrs jscyynerrs -#define yylloc jscyylloc - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NULLTOKEN = 258, - TRUETOKEN = 259, - FALSETOKEN = 260, - BREAK = 261, - CASE = 262, - DEFAULT = 263, - FOR = 264, - NEW = 265, - VAR = 266, - CONSTTOKEN = 267, - CONTINUE = 268, - FUNCTION = 269, - RETURN = 270, - VOIDTOKEN = 271, - DELETETOKEN = 272, - IF = 273, - THISTOKEN = 274, - DO = 275, - WHILE = 276, - INTOKEN = 277, - INSTANCEOF = 278, - TYPEOF = 279, - SWITCH = 280, - WITH = 281, - RESERVED = 282, - THROW = 283, - TRY = 284, - CATCH = 285, - FINALLY = 286, - DEBUGGER = 287, - IF_WITHOUT_ELSE = 288, - ELSE = 289, - EQEQ = 290, - NE = 291, - STREQ = 292, - STRNEQ = 293, - LE = 294, - GE = 295, - OR = 296, - AND = 297, - PLUSPLUS = 298, - MINUSMINUS = 299, - LSHIFT = 300, - RSHIFT = 301, - URSHIFT = 302, - PLUSEQUAL = 303, - MINUSEQUAL = 304, - MULTEQUAL = 305, - DIVEQUAL = 306, - LSHIFTEQUAL = 307, - RSHIFTEQUAL = 308, - URSHIFTEQUAL = 309, - ANDEQUAL = 310, - MODEQUAL = 311, - XOREQUAL = 312, - OREQUAL = 313, - OPENBRACE = 314, - CLOSEBRACE = 315, - NUMBER = 316, - IDENT = 317, - STRING = 318, - AUTOPLUSPLUS = 319, - AUTOMINUSMINUS = 320 - }; -#endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - - - +#define yyparse jscyyparse +#define yylex jscyylex +#define yyerror jscyyerror +#define yylval jscyylval +#define yychar jscyychar +#define yydebug jscyydebug +#define yynerrs jscyynerrs +#define yylloc jscyylloc /* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ #line 3 "../parser/Grammar.y" @@ -236,6 +104,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Lexer.h" #include "NodeConstructors.h" #include "NodeInfo.h" #include <stdlib.h> @@ -257,7 +126,6 @@ #define YYERROR_VERBOSE #endif -int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); @@ -352,6 +220,9 @@ static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserAr +/* Line 189 of yacc.c */ +#line 225 "JavaScriptCore/tmp/../generated/Grammar.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -370,10 +241,88 @@ static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserAr # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NULLTOKEN = 258, + TRUETOKEN = 259, + FALSETOKEN = 260, + BREAK = 261, + CASE = 262, + DEFAULT = 263, + FOR = 264, + NEW = 265, + VAR = 266, + CONSTTOKEN = 267, + CONTINUE = 268, + FUNCTION = 269, + RETURN = 270, + VOIDTOKEN = 271, + DELETETOKEN = 272, + IF = 273, + THISTOKEN = 274, + DO = 275, + WHILE = 276, + INTOKEN = 277, + INSTANCEOF = 278, + TYPEOF = 279, + SWITCH = 280, + WITH = 281, + RESERVED = 282, + THROW = 283, + TRY = 284, + CATCH = 285, + FINALLY = 286, + DEBUGGER = 287, + IF_WITHOUT_ELSE = 288, + ELSE = 289, + EQEQ = 290, + NE = 291, + STREQ = 292, + STRNEQ = 293, + LE = 294, + GE = 295, + OR = 296, + AND = 297, + PLUSPLUS = 298, + MINUSMINUS = 299, + LSHIFT = 300, + RSHIFT = 301, + URSHIFT = 302, + PLUSEQUAL = 303, + MINUSEQUAL = 304, + MULTEQUAL = 305, + DIVEQUAL = 306, + LSHIFTEQUAL = 307, + RSHIFTEQUAL = 308, + URSHIFTEQUAL = 309, + ANDEQUAL = 310, + MODEQUAL = 311, + XOREQUAL = 312, + OREQUAL = 313, + OPENBRACE = 314, + CLOSEBRACE = 315, + NUMBER = 316, + IDENT = 317, + STRING = 318, + AUTOPLUSPLUS = 319, + AUTOMINUSMINUS = 320 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 146 "../parser/Grammar.y" { + +/* Line 214 of yacc.c */ +#line 146 "../parser/Grammar.y" + int intValue; double doubleValue; const Identifier* ident; @@ -403,13 +352,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 187 of yacc.c. */ -#line 409 "JavaScriptCore/tmp/../generated/Grammar.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 360 "JavaScriptCore/tmp/../generated/Grammar.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -427,6 +378,8 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ + +/* Line 264 of yacc.c */ #line 178 "../parser/Grammar.y" @@ -442,8 +395,8 @@ static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned -/* Line 216 of yacc.c. */ -#line 447 "JavaScriptCore/tmp/../generated/Grammar.tab.c" +/* Line 264 of yacc.c */ +#line 400 "JavaScriptCore/tmp/../generated/Grammar.tab.c" #ifdef short # undef short @@ -518,14 +471,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -607,9 +560,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -644,12 +597,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -2363,17 +2316,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -2408,11 +2364,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -2694,10 +2650,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -2716,10 +2670,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -2743,88 +2696,97 @@ yyparse () #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; -/* Location data for the look-ahead symbol. */ +/* Location data for the lookahead symbol. */ YYLTYPE yylloc; - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + /* Number of syntax errors so far. */ + int yynerrs; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; - YYSIZE_T yystacksize = YYINITDEPTH; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; yylsp = yyls; + #if YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; + yylloc.first_column = yylloc.last_column = 1; #endif goto yysetstate; @@ -2863,6 +2825,7 @@ YYLTYPE yylloc; &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); + yyls = yyls1; yyss = yyss1; yyvs = yyvs1; @@ -2884,9 +2847,9 @@ YYLTYPE yylloc; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2907,6 +2870,9 @@ YYLTYPE yylloc; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -2915,16 +2881,16 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2956,20 +2922,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -3010,31 +2972,43 @@ yyreduce: switch (yyn) { case 2: + +/* Line 1455 of yacc.c */ #line 293 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NullNode(GLOBAL_DATA), 0, 1); ;} break; case 3: + +/* Line 1455 of yacc.c */ #line 294 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, true), 0, 1); ;} break; case 4: + +/* Line 1455 of yacc.c */ #line 295 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, false), 0, 1); ;} break; case 5: + +/* Line 1455 of yacc.c */ #line 296 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, (yyvsp[(1) - (1)].doubleValue)), 0, 1); ;} break; case 6: + +/* Line 1455 of yacc.c */ #line 297 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)), 0, 1); ;} break; case 7: + +/* Line 1455 of yacc.c */ #line 298 "../parser/Grammar.y" { Lexer& l = *GLOBAL_DATA->lexer; @@ -3050,6 +3024,8 @@ yyreduce: break; case 8: + +/* Line 1455 of yacc.c */ #line 309 "../parser/Grammar.y" { Lexer& l = *GLOBAL_DATA->lexer; @@ -3065,26 +3041,36 @@ yyreduce: break; case 9: + +/* Line 1455 of yacc.c */ #line 323 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 10: + +/* Line 1455 of yacc.c */ #line 324 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 11: + +/* Line 1455 of yacc.c */ #line 325 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, (yyvsp[(1) - (3)].doubleValue), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 12: + +/* Line 1455 of yacc.c */ #line 326 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), 0, (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); if (!(yyval.propertyNode).m_node) YYABORT; ;} break; case 13: + +/* Line 1455 of yacc.c */ #line 328 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (8)].ident), *(yyvsp[(2) - (8)].ident), (yyvsp[(4) - (8)].parameterList).m_node.head, (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line)), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -3097,6 +3083,8 @@ yyreduce: break; case 14: + +/* Line 1455 of yacc.c */ #line 339 "../parser/Grammar.y" { (yyval.propertyList).m_node.head = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].propertyNode).m_node); (yyval.propertyList).m_node.tail = (yyval.propertyList).m_node.head; @@ -3105,6 +3093,8 @@ yyreduce: break; case 15: + +/* Line 1455 of yacc.c */ #line 343 "../parser/Grammar.y" { (yyval.propertyList).m_node.head = (yyvsp[(1) - (3)].propertyList).m_node.head; (yyval.propertyList).m_node.tail = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, (yyvsp[(3) - (3)].propertyNode).m_node, (yyvsp[(1) - (3)].propertyList).m_node.tail); @@ -3113,51 +3103,71 @@ yyreduce: break; case 17: + +/* Line 1455 of yacc.c */ #line 351 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA), 0, 0); ;} break; case 18: + +/* Line 1455 of yacc.c */ #line 352 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (3)].propertyList).m_node.head), (yyvsp[(2) - (3)].propertyList).m_features, (yyvsp[(2) - (3)].propertyList).m_numConstants); ;} break; case 19: + +/* Line 1455 of yacc.c */ #line 354 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (4)].propertyList).m_node.head), (yyvsp[(2) - (4)].propertyList).m_features, (yyvsp[(2) - (4)].propertyList).m_numConstants); ;} break; case 20: + +/* Line 1455 of yacc.c */ #line 358 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ThisNode(GLOBAL_DATA), ThisFeature, 0); ;} break; case 23: + +/* Line 1455 of yacc.c */ #line 361 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), (yylsp[(1) - (1)]).first_column), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 24: + +/* Line 1455 of yacc.c */ #line 362 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (3)].expressionNode); ;} break; case 25: + +/* Line 1455 of yacc.c */ #line 366 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].intValue)), 0, (yyvsp[(2) - (3)].intValue) ? 1 : 0); ;} break; case 26: + +/* Line 1455 of yacc.c */ #line 367 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].elementList).m_node.head), (yyvsp[(2) - (3)].elementList).m_features, (yyvsp[(2) - (3)].elementList).m_numConstants); ;} break; case 27: + +/* Line 1455 of yacc.c */ #line 368 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(4) - (5)].intValue), (yyvsp[(2) - (5)].elementList).m_node.head), (yyvsp[(2) - (5)].elementList).m_features, (yyvsp[(4) - (5)].intValue) ? (yyvsp[(2) - (5)].elementList).m_numConstants + 1 : (yyvsp[(2) - (5)].elementList).m_numConstants); ;} break; case 28: + +/* Line 1455 of yacc.c */ #line 372 "../parser/Grammar.y" { (yyval.elementList).m_node.head = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].intValue), (yyvsp[(2) - (2)].expressionNode).m_node); (yyval.elementList).m_node.tail = (yyval.elementList).m_node.head; @@ -3166,6 +3176,8 @@ yyreduce: break; case 29: + +/* Line 1455 of yacc.c */ #line 377 "../parser/Grammar.y" { (yyval.elementList).m_node.head = (yyvsp[(1) - (4)].elementList).m_node.head; (yyval.elementList).m_node.tail = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, (yyvsp[(1) - (4)].elementList).m_node.tail, (yyvsp[(3) - (4)].intValue), (yyvsp[(4) - (4)].expressionNode).m_node); @@ -3174,26 +3186,36 @@ yyreduce: break; case 30: + +/* Line 1455 of yacc.c */ #line 384 "../parser/Grammar.y" { (yyval.intValue) = 0; ;} break; case 32: + +/* Line 1455 of yacc.c */ #line 389 "../parser/Grammar.y" { (yyval.intValue) = 1; ;} break; case 33: + +/* Line 1455 of yacc.c */ #line 390 "../parser/Grammar.y" { (yyval.intValue) = (yyvsp[(1) - (2)].intValue) + 1; ;} break; case 35: + +/* Line 1455 of yacc.c */ #line 395 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>((yyvsp[(1) - (1)].funcExprNode).m_node, (yyvsp[(1) - (1)].funcExprNode).m_features, (yyvsp[(1) - (1)].funcExprNode).m_numConstants); ;} break; case 36: + +/* Line 1455 of yacc.c */ #line 396 "../parser/Grammar.y" { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3202,6 +3224,8 @@ yyreduce: break; case 37: + +/* Line 1455 of yacc.c */ #line 400 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3210,6 +3234,8 @@ yyreduce: break; case 38: + +/* Line 1455 of yacc.c */ #line 404 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3218,6 +3244,8 @@ yyreduce: break; case 40: + +/* Line 1455 of yacc.c */ #line 412 "../parser/Grammar.y" { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3226,6 +3254,8 @@ yyreduce: break; case 41: + +/* Line 1455 of yacc.c */ #line 416 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3234,6 +3264,8 @@ yyreduce: break; case 42: + +/* Line 1455 of yacc.c */ #line 420 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3242,6 +3274,8 @@ yyreduce: break; case 44: + +/* Line 1455 of yacc.c */ #line 428 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3250,6 +3284,8 @@ yyreduce: break; case 46: + +/* Line 1455 of yacc.c */ #line 436 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3258,16 +3294,22 @@ yyreduce: break; case 47: + +/* Line 1455 of yacc.c */ #line 443 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 48: + +/* Line 1455 of yacc.c */ #line 444 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 49: + +/* Line 1455 of yacc.c */ #line 445 "../parser/Grammar.y" { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3276,6 +3318,8 @@ yyreduce: break; case 50: + +/* Line 1455 of yacc.c */ #line 449 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3283,16 +3327,22 @@ yyreduce: break; case 51: + +/* Line 1455 of yacc.c */ #line 455 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 52: + +/* Line 1455 of yacc.c */ #line 456 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 53: + +/* Line 1455 of yacc.c */ #line 457 "../parser/Grammar.y" { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3301,6 +3351,8 @@ yyreduce: break; case 54: + +/* Line 1455 of yacc.c */ #line 461 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3309,16 +3361,22 @@ yyreduce: break; case 55: + +/* Line 1455 of yacc.c */ #line 468 "../parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA), 0, 0); ;} break; case 56: + +/* Line 1455 of yacc.c */ #line 469 "../parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA, (yyvsp[(2) - (3)].argumentList).m_node.head), (yyvsp[(2) - (3)].argumentList).m_features, (yyvsp[(2) - (3)].argumentList).m_numConstants); ;} break; case 57: + +/* Line 1455 of yacc.c */ #line 473 "../parser/Grammar.y" { (yyval.argumentList).m_node.head = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].expressionNode).m_node); (yyval.argumentList).m_node.tail = (yyval.argumentList).m_node.head; @@ -3327,6 +3385,8 @@ yyreduce: break; case 58: + +/* Line 1455 of yacc.c */ #line 477 "../parser/Grammar.y" { (yyval.argumentList).m_node.head = (yyvsp[(1) - (3)].argumentList).m_node.head; (yyval.argumentList).m_node.tail = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (3)].argumentList).m_node.tail, (yyvsp[(3) - (3)].expressionNode).m_node); @@ -3335,181 +3395,253 @@ yyreduce: break; case 64: + +/* Line 1455 of yacc.c */ #line 495 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 65: + +/* Line 1455 of yacc.c */ #line 496 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 67: + +/* Line 1455 of yacc.c */ #line 501 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 68: + +/* Line 1455 of yacc.c */ #line 502 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 69: + +/* Line 1455 of yacc.c */ #line 506 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDeleteNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 70: + +/* Line 1455 of yacc.c */ #line 507 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) VoidNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants + 1); ;} break; case 71: + +/* Line 1455 of yacc.c */ #line 508 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeTypeOfNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 72: + +/* Line 1455 of yacc.c */ #line 509 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 73: + +/* Line 1455 of yacc.c */ #line 510 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 74: + +/* Line 1455 of yacc.c */ #line 511 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 75: + +/* Line 1455 of yacc.c */ #line 512 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 76: + +/* Line 1455 of yacc.c */ #line 513 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 77: + +/* Line 1455 of yacc.c */ #line 514 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeNegateNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 78: + +/* Line 1455 of yacc.c */ #line 515 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeBitwiseNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 79: + +/* Line 1455 of yacc.c */ #line 516 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 85: + +/* Line 1455 of yacc.c */ #line 530 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 86: + +/* Line 1455 of yacc.c */ #line 531 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 87: + +/* Line 1455 of yacc.c */ #line 532 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 89: + +/* Line 1455 of yacc.c */ #line 538 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 90: + +/* Line 1455 of yacc.c */ #line 540 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 91: + +/* Line 1455 of yacc.c */ #line 542 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 93: + +/* Line 1455 of yacc.c */ #line 547 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 94: + +/* Line 1455 of yacc.c */ #line 548 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 96: + +/* Line 1455 of yacc.c */ #line 554 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 97: + +/* Line 1455 of yacc.c */ #line 556 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 99: + +/* Line 1455 of yacc.c */ #line 561 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 100: + +/* Line 1455 of yacc.c */ #line 562 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 101: + +/* Line 1455 of yacc.c */ #line 563 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 103: + +/* Line 1455 of yacc.c */ #line 568 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 104: + +/* Line 1455 of yacc.c */ #line 569 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 105: + +/* Line 1455 of yacc.c */ #line 570 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 107: + +/* Line 1455 of yacc.c */ #line 575 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 108: + +/* Line 1455 of yacc.c */ #line 576 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 109: + +/* Line 1455 of yacc.c */ #line 577 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 110: + +/* Line 1455 of yacc.c */ #line 578 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 111: + +/* Line 1455 of yacc.c */ #line 579 "../parser/Grammar.y" { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3517,6 +3649,8 @@ yyreduce: break; case 112: + +/* Line 1455 of yacc.c */ #line 582 "../parser/Grammar.y" { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3524,26 +3658,36 @@ yyreduce: break; case 114: + +/* Line 1455 of yacc.c */ #line 589 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 115: + +/* Line 1455 of yacc.c */ #line 590 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 116: + +/* Line 1455 of yacc.c */ #line 591 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 117: + +/* Line 1455 of yacc.c */ #line 592 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 118: + +/* Line 1455 of yacc.c */ #line 594 "../parser/Grammar.y" { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3551,26 +3695,36 @@ yyreduce: break; case 120: + +/* Line 1455 of yacc.c */ #line 601 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 121: + +/* Line 1455 of yacc.c */ #line 602 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 122: + +/* Line 1455 of yacc.c */ #line 603 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 123: + +/* Line 1455 of yacc.c */ #line 604 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 124: + +/* Line 1455 of yacc.c */ #line 606 "../parser/Grammar.y" { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3578,6 +3732,8 @@ yyreduce: break; case 125: + +/* Line 1455 of yacc.c */ #line 610 "../parser/Grammar.y" { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3585,156 +3741,218 @@ yyreduce: break; case 127: + +/* Line 1455 of yacc.c */ #line 617 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 128: + +/* Line 1455 of yacc.c */ #line 618 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 129: + +/* Line 1455 of yacc.c */ #line 619 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 130: + +/* Line 1455 of yacc.c */ #line 620 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 132: + +/* Line 1455 of yacc.c */ #line 626 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 133: + +/* Line 1455 of yacc.c */ #line 628 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 134: + +/* Line 1455 of yacc.c */ #line 630 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 135: + +/* Line 1455 of yacc.c */ #line 632 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 137: + +/* Line 1455 of yacc.c */ #line 638 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 138: + +/* Line 1455 of yacc.c */ #line 639 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 139: + +/* Line 1455 of yacc.c */ #line 641 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 140: + +/* Line 1455 of yacc.c */ #line 643 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 142: + +/* Line 1455 of yacc.c */ #line 648 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 144: + +/* Line 1455 of yacc.c */ #line 654 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 146: + +/* Line 1455 of yacc.c */ #line 659 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 148: + +/* Line 1455 of yacc.c */ #line 664 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 150: + +/* Line 1455 of yacc.c */ #line 670 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 152: + +/* Line 1455 of yacc.c */ #line 676 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 154: + +/* Line 1455 of yacc.c */ #line 681 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 156: + +/* Line 1455 of yacc.c */ #line 687 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 158: + +/* Line 1455 of yacc.c */ #line 693 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 160: + +/* Line 1455 of yacc.c */ #line 698 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 162: + +/* Line 1455 of yacc.c */ #line 704 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 164: + +/* Line 1455 of yacc.c */ #line 710 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 166: + +/* Line 1455 of yacc.c */ #line 715 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 168: + +/* Line 1455 of yacc.c */ #line 721 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 170: + +/* Line 1455 of yacc.c */ #line 726 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 172: + +/* Line 1455 of yacc.c */ #line 732 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 174: + +/* Line 1455 of yacc.c */ #line 738 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 176: + +/* Line 1455 of yacc.c */ #line 744 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 178: + +/* Line 1455 of yacc.c */ #line 750 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3742,6 +3960,8 @@ yyreduce: break; case 180: + +/* Line 1455 of yacc.c */ #line 758 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3749,6 +3969,8 @@ yyreduce: break; case 182: + +/* Line 1455 of yacc.c */ #line 766 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3756,99 +3978,137 @@ yyreduce: break; case 183: + +/* Line 1455 of yacc.c */ #line 772 "../parser/Grammar.y" { (yyval.op) = OpEqual; ;} break; case 184: + +/* Line 1455 of yacc.c */ #line 773 "../parser/Grammar.y" { (yyval.op) = OpPlusEq; ;} break; case 185: + +/* Line 1455 of yacc.c */ #line 774 "../parser/Grammar.y" { (yyval.op) = OpMinusEq; ;} break; case 186: + +/* Line 1455 of yacc.c */ #line 775 "../parser/Grammar.y" { (yyval.op) = OpMultEq; ;} break; case 187: + +/* Line 1455 of yacc.c */ #line 776 "../parser/Grammar.y" { (yyval.op) = OpDivEq; ;} break; case 188: + +/* Line 1455 of yacc.c */ #line 777 "../parser/Grammar.y" { (yyval.op) = OpLShift; ;} break; case 189: + +/* Line 1455 of yacc.c */ #line 778 "../parser/Grammar.y" { (yyval.op) = OpRShift; ;} break; case 190: + +/* Line 1455 of yacc.c */ #line 779 "../parser/Grammar.y" { (yyval.op) = OpURShift; ;} break; case 191: + +/* Line 1455 of yacc.c */ #line 780 "../parser/Grammar.y" { (yyval.op) = OpAndEq; ;} break; case 192: + +/* Line 1455 of yacc.c */ #line 781 "../parser/Grammar.y" { (yyval.op) = OpXOrEq; ;} break; case 193: + +/* Line 1455 of yacc.c */ #line 782 "../parser/Grammar.y" { (yyval.op) = OpOrEq; ;} break; case 194: + +/* Line 1455 of yacc.c */ #line 783 "../parser/Grammar.y" { (yyval.op) = OpModEq; ;} break; case 196: + +/* Line 1455 of yacc.c */ #line 788 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 198: + +/* Line 1455 of yacc.c */ #line 793 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 200: + +/* Line 1455 of yacc.c */ #line 798 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 218: + +/* Line 1455 of yacc.c */ #line 822 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 219: + +/* Line 1455 of yacc.c */ #line 824 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].sourceElements).m_node), (yyvsp[(2) - (3)].sourceElements).m_varDeclarations, (yyvsp[(2) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (3)].sourceElements).m_features, (yyvsp[(2) - (3)].sourceElements).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 220: + +/* Line 1455 of yacc.c */ #line 829 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 221: + +/* Line 1455 of yacc.c */ #line 831 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); @@ -3856,6 +4116,8 @@ yyreduce: break; case 222: + +/* Line 1455 of yacc.c */ #line 837 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; @@ -3867,6 +4129,8 @@ yyreduce: break; case 223: + +/* Line 1455 of yacc.c */ #line 844 "../parser/Grammar.y" { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3880,6 +4144,8 @@ yyreduce: break; case 224: + +/* Line 1455 of yacc.c */ #line 854 "../parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3891,6 +4157,8 @@ yyreduce: break; case 225: + +/* Line 1455 of yacc.c */ #line 862 "../parser/Grammar.y" { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3904,6 +4172,8 @@ yyreduce: break; case 226: + +/* Line 1455 of yacc.c */ #line 874 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; @@ -3915,6 +4185,8 @@ yyreduce: break; case 227: + +/* Line 1455 of yacc.c */ #line 881 "../parser/Grammar.y" { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3928,6 +4200,8 @@ yyreduce: break; case 228: + +/* Line 1455 of yacc.c */ #line 891 "../parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3939,6 +4213,8 @@ yyreduce: break; case 229: + +/* Line 1455 of yacc.c */ #line 899 "../parser/Grammar.y" { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3952,18 +4228,24 @@ yyreduce: break; case 230: + +/* Line 1455 of yacc.c */ #line 911 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 231: + +/* Line 1455 of yacc.c */ #line 914 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 232: + +/* Line 1455 of yacc.c */ #line 919 "../parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (1)].constDeclNode).m_node; (yyval.constDeclList).m_node.tail = (yyval.constDeclList).m_node.head; @@ -3976,6 +4258,8 @@ yyreduce: break; case 233: + +/* Line 1455 of yacc.c */ #line 928 "../parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (3)].constDeclList).m_node.head; (yyvsp[(1) - (3)].constDeclList).m_node.tail->m_next = (yyvsp[(3) - (3)].constDeclNode).m_node; @@ -3988,49 +4272,67 @@ yyreduce: break; case 234: + +/* Line 1455 of yacc.c */ #line 939 "../parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), 0), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 235: + +/* Line 1455 of yacc.c */ #line 940 "../parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node), ((*(yyvsp[(1) - (2)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 236: + +/* Line 1455 of yacc.c */ #line 944 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 237: + +/* Line 1455 of yacc.c */ #line 948 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 238: + +/* Line 1455 of yacc.c */ #line 952 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); ;} break; case 239: + +/* Line 1455 of yacc.c */ #line 956 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 240: + +/* Line 1455 of yacc.c */ #line 958 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 241: + +/* Line 1455 of yacc.c */ #line 964 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 242: + +/* Line 1455 of yacc.c */ #line 967 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].statementNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), @@ -4041,24 +4343,32 @@ yyreduce: break; case 243: + +/* Line 1455 of yacc.c */ #line 976 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 244: + +/* Line 1455 of yacc.c */ #line 978 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 245: + +/* Line 1455 of yacc.c */ #line 980 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 246: + +/* Line 1455 of yacc.c */ #line 983 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, (yyvsp[(3) - (9)].expressionNode).m_node, (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, false), (yyvsp[(9) - (9)].statementNode).m_varDeclarations, (yyvsp[(9) - (9)].statementNode).m_funcDeclarations, (yyvsp[(3) - (9)].expressionNode).m_features | (yyvsp[(5) - (9)].expressionNode).m_features | (yyvsp[(7) - (9)].expressionNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features, @@ -4068,6 +4378,8 @@ yyreduce: break; case 247: + +/* Line 1455 of yacc.c */ #line 989 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, (yyvsp[(4) - (10)].varDeclList).m_node, (yyvsp[(6) - (10)].expressionNode).m_node, (yyvsp[(8) - (10)].expressionNode).m_node, (yyvsp[(10) - (10)].statementNode).m_node, true), mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_varDeclarations, (yyvsp[(10) - (10)].statementNode).m_varDeclarations), @@ -4078,6 +4390,8 @@ yyreduce: break; case 248: + +/* Line 1455 of yacc.c */ #line 996 "../parser/Grammar.y" { ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node); @@ -4090,6 +4404,8 @@ yyreduce: break; case 249: + +/* Line 1455 of yacc.c */ #line 1005 "../parser/Grammar.y" { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (8)].ident), 0, (yyvsp[(6) - (8)].expressionNode).m_node, (yyvsp[(8) - (8)].statementNode).m_node, (yylsp[(5) - (8)]).first_column, (yylsp[(5) - (8)]).first_column - (yylsp[(4) - (8)]).first_column, (yylsp[(6) - (8)]).last_column - (yylsp[(5) - (8)]).first_column); setExceptionLocation(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column); @@ -4099,6 +4415,8 @@ yyreduce: break; case 250: + +/* Line 1455 of yacc.c */ #line 1011 "../parser/Grammar.y" { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (9)].ident), (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, (yylsp[(5) - (9)]).first_column, (yylsp[(5) - (9)]).first_column - (yylsp[(4) - (9)]).first_column, (yylsp[(5) - (9)]).last_column - (yylsp[(5) - (9)]).first_column); setExceptionLocation(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column); @@ -4110,16 +4428,22 @@ yyreduce: break; case 251: + +/* Line 1455 of yacc.c */ #line 1021 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;} break; case 253: + +/* Line 1455 of yacc.c */ #line 1026 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;} break; case 255: + +/* Line 1455 of yacc.c */ #line 1031 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4128,6 +4452,8 @@ yyreduce: break; case 256: + +/* Line 1455 of yacc.c */ #line 1035 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4136,6 +4462,8 @@ yyreduce: break; case 257: + +/* Line 1455 of yacc.c */ #line 1039 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4144,6 +4472,8 @@ yyreduce: break; case 258: + +/* Line 1455 of yacc.c */ #line 1043 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4152,6 +4482,8 @@ yyreduce: break; case 259: + +/* Line 1455 of yacc.c */ #line 1050 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4159,6 +4491,8 @@ yyreduce: break; case 260: + +/* Line 1455 of yacc.c */ #line 1053 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4166,6 +4500,8 @@ yyreduce: break; case 261: + +/* Line 1455 of yacc.c */ #line 1056 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4173,6 +4509,8 @@ yyreduce: break; case 262: + +/* Line 1455 of yacc.c */ #line 1059 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4180,6 +4518,8 @@ yyreduce: break; case 263: + +/* Line 1455 of yacc.c */ #line 1065 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4187,6 +4527,8 @@ yyreduce: break; case 264: + +/* Line 1455 of yacc.c */ #line 1068 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4194,6 +4536,8 @@ yyreduce: break; case 265: + +/* Line 1455 of yacc.c */ #line 1071 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4201,6 +4545,8 @@ yyreduce: break; case 266: + +/* Line 1455 of yacc.c */ #line 1074 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4208,6 +4554,8 @@ yyreduce: break; case 267: + +/* Line 1455 of yacc.c */ #line 1080 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node, (yylsp[(3) - (5)]).last_column, (yylsp[(3) - (5)]).last_column - (yylsp[(3) - (5)]).first_column), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features | WithFeature, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); @@ -4215,6 +4563,8 @@ yyreduce: break; case 268: + +/* Line 1455 of yacc.c */ #line 1086 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].caseBlockNode).m_node), (yyvsp[(5) - (5)].caseBlockNode).m_varDeclarations, (yyvsp[(5) - (5)].caseBlockNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].caseBlockNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].caseBlockNode).m_numConstants); @@ -4222,11 +4572,15 @@ yyreduce: break; case 269: + +/* Line 1455 of yacc.c */ #line 1092 "../parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].clauseList).m_node.head, 0, 0), (yyvsp[(2) - (3)].clauseList).m_varDeclarations, (yyvsp[(2) - (3)].clauseList).m_funcDeclarations, (yyvsp[(2) - (3)].clauseList).m_features, (yyvsp[(2) - (3)].clauseList).m_numConstants); ;} break; case 270: + +/* Line 1455 of yacc.c */ #line 1094 "../parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (5)].clauseList).m_node.head, (yyvsp[(3) - (5)].caseClauseNode).m_node, (yyvsp[(4) - (5)].clauseList).m_node.head), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_varDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_varDeclarations), (yyvsp[(4) - (5)].clauseList).m_varDeclarations), @@ -4236,11 +4590,15 @@ yyreduce: break; case 271: + +/* Line 1455 of yacc.c */ #line 1102 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = 0; (yyval.clauseList).m_node.tail = 0; (yyval.clauseList).m_varDeclarations = 0; (yyval.clauseList).m_funcDeclarations = 0; (yyval.clauseList).m_features = 0; (yyval.clauseList).m_numConstants = 0; ;} break; case 273: + +/* Line 1455 of yacc.c */ #line 1107 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].caseClauseNode).m_node); (yyval.clauseList).m_node.tail = (yyval.clauseList).m_node.head; @@ -4251,6 +4609,8 @@ yyreduce: break; case 274: + +/* Line 1455 of yacc.c */ #line 1113 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = (yyvsp[(1) - (2)].clauseList).m_node.head; (yyval.clauseList).m_node.tail = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (2)].clauseList).m_node.tail, (yyvsp[(2) - (2)].caseClauseNode).m_node); @@ -4262,26 +4622,36 @@ yyreduce: break; case 275: + +/* Line 1455 of yacc.c */ #line 1123 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node), 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); ;} break; case 276: + +/* Line 1455 of yacc.c */ #line 1124 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].sourceElements).m_node), (yyvsp[(4) - (4)].sourceElements).m_varDeclarations, (yyvsp[(4) - (4)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (4)].expressionNode).m_features | (yyvsp[(4) - (4)].sourceElements).m_features, (yyvsp[(2) - (4)].expressionNode).m_numConstants + (yyvsp[(4) - (4)].sourceElements).m_numConstants); ;} break; case 277: + +/* Line 1455 of yacc.c */ #line 1128 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); ;} break; case 278: + +/* Line 1455 of yacc.c */ #line 1129 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0, (yyvsp[(3) - (3)].sourceElements).m_node), (yyvsp[(3) - (3)].sourceElements).m_varDeclarations, (yyvsp[(3) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(3) - (3)].sourceElements).m_features, (yyvsp[(3) - (3)].sourceElements).m_numConstants); ;} break; case 279: + +/* Line 1455 of yacc.c */ #line 1133 "../parser/Grammar.y" { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].statementNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4289,6 +4659,8 @@ yyreduce: break; case 280: + +/* Line 1455 of yacc.c */ #line 1139 "../parser/Grammar.y" { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4297,6 +4669,8 @@ yyreduce: break; case 281: + +/* Line 1455 of yacc.c */ #line 1143 "../parser/Grammar.y" { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4305,6 +4679,8 @@ yyreduce: break; case 282: + +/* Line 1455 of yacc.c */ #line 1150 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (4)].statementNode).m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, (yyvsp[(4) - (4)].statementNode).m_node), mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_varDeclarations, (yyvsp[(4) - (4)].statementNode).m_varDeclarations), @@ -4315,6 +4691,8 @@ yyreduce: break; case 283: + +/* Line 1455 of yacc.c */ #line 1156 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, *(yyvsp[(5) - (7)].ident), ((yyvsp[(7) - (7)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (7)].statementNode).m_node, 0), mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), @@ -4325,6 +4703,8 @@ yyreduce: break; case 284: + +/* Line 1455 of yacc.c */ #line 1163 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (9)].statementNode).m_node, *(yyvsp[(5) - (9)].ident), ((yyvsp[(7) - (9)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (9)].statementNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_varDeclarations, (yyvsp[(7) - (9)].statementNode).m_varDeclarations), (yyvsp[(9) - (9)].statementNode).m_varDeclarations), @@ -4335,23 +4715,31 @@ yyreduce: break; case 285: + +/* Line 1455 of yacc.c */ #line 1172 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 286: + +/* Line 1455 of yacc.c */ #line 1174 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 287: + +/* Line 1455 of yacc.c */ #line 1179 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*(yyvsp[(2) - (7)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); (yyval.statementNode).m_funcDeclarations->data.append(static_cast<FuncDeclNode*>((yyval.statementNode).m_node)->body()); ;} break; case 288: + +/* Line 1455 of yacc.c */ #line 1181 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*(yyvsp[(2) - (8)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4363,11 +4751,15 @@ yyreduce: break; case 289: + +/* Line 1455 of yacc.c */ #line 1191 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(5) - (6)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(4) - (6)].intValue), (yyvsp[(6) - (6)].intValue), (yylsp[(4) - (6)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(5) - (6)].functionBodyNode), (yylsp[(4) - (6)]), (yylsp[(6) - (6)])); ;} break; case 290: + +/* Line 1455 of yacc.c */ #line 1193 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line), (yyvsp[(3) - (7)].parameterList).m_node.head), (yyvsp[(3) - (7)].parameterList).m_features | ClosureFeature, 0); @@ -4378,11 +4770,15 @@ yyreduce: break; case 291: + +/* Line 1455 of yacc.c */ #line 1199 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;} break; case 292: + +/* Line 1455 of yacc.c */ #line 1201 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4393,6 +4789,8 @@ yyreduce: break; case 293: + +/* Line 1455 of yacc.c */ #line 1210 "../parser/Grammar.y" { (yyval.parameterList).m_node.head = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)); (yyval.parameterList).m_features = (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; @@ -4400,6 +4798,8 @@ yyreduce: break; case 294: + +/* Line 1455 of yacc.c */ #line 1213 "../parser/Grammar.y" { (yyval.parameterList).m_node.head = (yyvsp[(1) - (3)].parameterList).m_node.head; (yyval.parameterList).m_features = (yyvsp[(1) - (3)].parameterList).m_features | ((*(yyvsp[(3) - (3)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); @@ -4407,27 +4807,37 @@ yyreduce: break; case 295: + +/* Line 1455 of yacc.c */ #line 1219 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 296: + +/* Line 1455 of yacc.c */ #line 1220 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 297: + +/* Line 1455 of yacc.c */ #line 1224 "../parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing(new (GLOBAL_DATA) SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, (yylsp[(0) - (0)]).last_line, 0); ;} break; case 298: + +/* Line 1455 of yacc.c */ #line 1225 "../parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing((yyvsp[(1) - (1)].sourceElements).m_node, (yyvsp[(1) - (1)].sourceElements).m_varDeclarations, (yyvsp[(1) - (1)].sourceElements).m_funcDeclarations, (yyvsp[(1) - (1)].sourceElements).m_features, (yylsp[(1) - (1)]).last_line, (yyvsp[(1) - (1)].sourceElements).m_numConstants); ;} break; case 299: + +/* Line 1455 of yacc.c */ #line 1230 "../parser/Grammar.y" { (yyval.sourceElements).m_node = new (GLOBAL_DATA) SourceElements(GLOBAL_DATA); (yyval.sourceElements).m_node->append((yyvsp[(1) - (1)].statementNode).m_node); @@ -4439,6 +4849,8 @@ yyreduce: break; case 300: + +/* Line 1455 of yacc.c */ #line 1237 "../parser/Grammar.y" { (yyval.sourceElements).m_node->append((yyvsp[(2) - (2)].statementNode).m_node); (yyval.sourceElements).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_varDeclarations, (yyvsp[(2) - (2)].statementNode).m_varDeclarations); @@ -4449,188 +4861,261 @@ yyreduce: break; case 304: + +/* Line 1455 of yacc.c */ #line 1251 "../parser/Grammar.y" { ;} break; case 305: + +/* Line 1455 of yacc.c */ #line 1252 "../parser/Grammar.y" { ;} break; case 306: + +/* Line 1455 of yacc.c */ #line 1253 "../parser/Grammar.y" { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;} break; case 307: + +/* Line 1455 of yacc.c */ #line 1254 "../parser/Grammar.y" { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;} break; case 308: + +/* Line 1455 of yacc.c */ #line 1258 "../parser/Grammar.y" { ;} break; case 309: + +/* Line 1455 of yacc.c */ #line 1259 "../parser/Grammar.y" { ;} break; case 310: + +/* Line 1455 of yacc.c */ #line 1260 "../parser/Grammar.y" { ;} break; case 311: + +/* Line 1455 of yacc.c */ #line 1261 "../parser/Grammar.y" { if (*(yyvsp[(1) - (7)].ident) != "get" && *(yyvsp[(1) - (7)].ident) != "set") YYABORT; ;} break; case 312: + +/* Line 1455 of yacc.c */ #line 1262 "../parser/Grammar.y" { if (*(yyvsp[(1) - (8)].ident) != "get" && *(yyvsp[(1) - (8)].ident) != "set") YYABORT; ;} break; case 316: + +/* Line 1455 of yacc.c */ #line 1272 "../parser/Grammar.y" { ;} break; case 317: + +/* Line 1455 of yacc.c */ #line 1273 "../parser/Grammar.y" { ;} break; case 318: + +/* Line 1455 of yacc.c */ #line 1275 "../parser/Grammar.y" { ;} break; case 322: + +/* Line 1455 of yacc.c */ #line 1282 "../parser/Grammar.y" { ;} break; case 517: + +/* Line 1455 of yacc.c */ #line 1650 "../parser/Grammar.y" { ;} break; case 518: + +/* Line 1455 of yacc.c */ #line 1651 "../parser/Grammar.y" { ;} break; case 520: + +/* Line 1455 of yacc.c */ #line 1656 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 521: + +/* Line 1455 of yacc.c */ #line 1660 "../parser/Grammar.y" { ;} break; case 522: + +/* Line 1455 of yacc.c */ #line 1661 "../parser/Grammar.y" { ;} break; case 525: + +/* Line 1455 of yacc.c */ #line 1667 "../parser/Grammar.y" { ;} break; case 526: + +/* Line 1455 of yacc.c */ #line 1668 "../parser/Grammar.y" { ;} break; case 530: + +/* Line 1455 of yacc.c */ #line 1675 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 533: + +/* Line 1455 of yacc.c */ #line 1684 "../parser/Grammar.y" { ;} break; case 534: + +/* Line 1455 of yacc.c */ #line 1685 "../parser/Grammar.y" { ;} break; case 539: + +/* Line 1455 of yacc.c */ #line 1702 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 555: + +/* Line 1455 of yacc.c */ #line 1733 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 557: + +/* Line 1455 of yacc.c */ #line 1735 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 559: + +/* Line 1455 of yacc.c */ #line 1740 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 561: + +/* Line 1455 of yacc.c */ #line 1742 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 563: + +/* Line 1455 of yacc.c */ #line 1747 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 565: + +/* Line 1455 of yacc.c */ #line 1749 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 568: + +/* Line 1455 of yacc.c */ #line 1761 "../parser/Grammar.y" { ;} break; case 569: + +/* Line 1455 of yacc.c */ #line 1762 "../parser/Grammar.y" { ;} break; case 578: + +/* Line 1455 of yacc.c */ #line 1786 "../parser/Grammar.y" { ;} break; case 580: + +/* Line 1455 of yacc.c */ #line 1791 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 585: + +/* Line 1455 of yacc.c */ #line 1802 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 592: + +/* Line 1455 of yacc.c */ #line 1818 "../parser/Grammar.y" { ;} break; -/* Line 1267 of yacc.c. */ -#line 4634 "JavaScriptCore/tmp/../generated/Grammar.tab.c" + +/* Line 1455 of yacc.c */ +#line 5119 "JavaScriptCore/tmp/../generated/Grammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4706,7 +5191,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -4723,7 +5208,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -4781,14 +5266,11 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ + the lookahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; @@ -4813,7 +5295,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -4824,7 +5306,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); /* Do not reclaim the symbols of the rule which action triggered @@ -4850,6 +5332,8 @@ yyreturn: } + +/* Line 1675 of yacc.c */ #line 1834 "../parser/Grammar.y" diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h index 1fdb03548f..a485e42cf8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h +++ b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +28,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -104,78 +104,16 @@ AUTOMINUSMINUS = 320 }; #endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 146 "../parser/Grammar.y" { + +/* Line 1676 of yacc.c */ +#line 146 "../parser/Grammar.y" + int intValue; double doubleValue; const Identifier* ident; @@ -205,13 +143,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 1489 of yacc.c. */ -#line 211 "JavaScriptCore/tmp/../generated/Grammar.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 151 "JavaScriptCore/tmp/../generated/Grammar.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif @@ -230,3 +170,4 @@ typedef struct YYLTYPE #endif + diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h b/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h index f912298cbf..c8ff849942 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h +++ b/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h @@ -4,7 +4,7 @@ namespace JSC { -static const struct HashTableValue stringTableValues[33] = { +static const struct HashTableValue stringTableValues[36] = { { "toString", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 }, { "valueOf", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 }, { "charAt", DontEnum|Function, (intptr_t)stringProtoFuncCharAt, (intptr_t)1 }, @@ -37,9 +37,12 @@ static const struct HashTableValue stringTableValues[33] = { { "fontsize", DontEnum|Function, (intptr_t)stringProtoFuncFontsize, (intptr_t)1 }, { "anchor", DontEnum|Function, (intptr_t)stringProtoFuncAnchor, (intptr_t)1 }, { "link", DontEnum|Function, (intptr_t)stringProtoFuncLink, (intptr_t)1 }, + { "trim", DontEnum|Function, (intptr_t)stringProtoFuncTrim, (intptr_t)0 }, + { "trimLeft", DontEnum|Function, (intptr_t)stringProtoFuncTrimLeft, (intptr_t)0 }, + { "trimRight", DontEnum|Function, (intptr_t)stringProtoFuncTrimRight, (intptr_t)0 }, { 0, 0, 0, 0 } }; extern JSC_CONST_HASHTABLE HashTable stringTable = - { 71, 63, stringTableValues, 0 }; + { 133, 127, stringTableValues, 0 }; } // namespace diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp index 847b1fad6a..db0edc4370 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp @@ -91,8 +91,8 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc) #if USE(INTERPRETER) NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -121,9 +121,9 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP { CodeBlock* codeBlock = callFrame->codeBlock(); - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; - int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain(); + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; + int skip = vPC[3].u.operand + codeBlock->needsFullScopeChain(); ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -152,12 +152,12 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int dst = (vPC + 1)->u.operand; - JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell); + int dst = vPC[1].u.operand; + JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); ASSERT(globalObject->isGlobalObject()); - int property = (vPC + 3)->u.operand; - Structure* structure = (vPC + 4)->u.structure; - int offset = (vPC + 5)->u.operand; + int property = vPC[3].u.operand; + Structure* structure = vPC[4].u.structure; + int offset = vPC[5].u.operand; if (structure == globalObject->structure()) { callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset)); @@ -192,16 +192,16 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC) { - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain())); } NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int baseDst = (vPC + 1)->u.operand; - int propDst = (vPC + 2)->u.operand; - int property = (vPC + 3)->u.operand; + int baseDst = vPC[1].u.operand; + int propDst = vPC[2].u.operand; + int property = vPC[3].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -233,51 +233,6 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst return false; } -NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) -{ - int baseDst = (vPC + 1)->u.operand; - int funcDst = (vPC + 2)->u.operand; - int property = (vPC + 3)->u.operand; - - ScopeChainNode* scopeChain = callFrame->scopeChain(); - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - - // FIXME: add scopeDepthIsZero optimization - - ASSERT(iter != end); - - CodeBlock* codeBlock = callFrame->codeBlock(); - Identifier& ident = codeBlock->identifier(property); - JSObject* base; - do { - base = *iter; - PropertySlot slot(base); - if (base->getPropertySlot(callFrame, ident, slot)) { - // ECMA 11.2.3 says that if we hit an activation the this value should be null. - // However, section 10.2.3 says that in the case where the value provided - // by the caller is null, the global object should be used. It also says - // that the section does not apply to internal functions, but for simplicity - // of implementation we use the global object anyway here. This guarantees - // that in host objects you always get a valid object for this. - // We also handle wrapper substitution for the global object at the same time. - JSObject* thisObj = base->toThisObject(callFrame); - JSValue result = slot.getValue(callFrame, ident); - exceptionValue = callFrame->globalData().exception; - if (exceptionValue) - return false; - - callFrame->r(baseDst) = JSValue(thisObj); - callFrame->r(funcDst) = JSValue(result); - return true; - } - ++iter; - } while (iter != end); - - exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock); - return false; -} - #endif // USE(INTERPRETER) ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc) @@ -928,10 +883,10 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook #if USE(INTERPRETER) NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC) { - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); - Identifier& property = codeBlock->identifier((++vPC)->u.operand); - JSValue value = callFrame->r((++vPC)->u.operand).jsValue(); + Identifier& property = codeBlock->identifier(vPC[2].u.operand); + JSValue value = callFrame->r(vPC[3].u.operand).jsValue(); JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete); callFrame->r(dst) = JSValue(scope); @@ -983,22 +938,20 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* return; } - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - vPC[0] = getOpcode(op_put_by_id_generic); - return; - } - // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { if (structure->isDictionary()) { vPC[0] = getOpcode(op_put_by_id_generic); return; } + + // put_by_id_transition checks the prototype chain for setters. + normalizePrototypeChain(callFrame, baseCell); + vPC[0] = getOpcode(op_put_by_id_transition); vPC[4] = structure->previousID(); vPC[5] = structure; - vPC[6] = protoChain; + vPC[6] = structure->prototypeChain(callFrame); vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); return; @@ -1076,6 +1029,11 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* return; } + if (structure->isDictionary()) { + vPC[0] = getOpcode(op_get_by_id_generic); + return; + } + if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { ASSERT(slot.slotBase().isObject()); @@ -1086,6 +1044,8 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* if (baseObject->structure()->isDictionary()) baseObject->setStructure(Structure::fromDictionaryTransition(baseObject->structure())); + ASSERT(!baseObject->structure()->isUncacheableDictionary()); + vPC[0] = getOpcode(op_get_by_id_proto); vPC[5] = baseObject->structure(); vPC[6] = slot.cachedOffset(); @@ -1094,21 +1054,15 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* return; } - size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); if (!count) { vPC[0] = getOpcode(op_get_by_id_generic); return; } - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - vPC[0] = getOpcode(op_get_by_id_generic); - return; - } - vPC[0] = getOpcode(op_get_by_id_chain); vPC[4] = structure; - vPC[5] = protoChain; + vPC[5] = structure->prototypeChain(callFrame); vPC[6] = count; vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); @@ -1213,10 +1167,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Constructs a new empty Object instance using the original constructor, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; callFrame->r(dst) = JSValue(constructEmptyObject(callFrame)); - ++vPC; + vPC += OPCODE_LENGTH(op_new_object); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_array) { @@ -1227,13 +1181,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi The array will contain argCount elements with values taken from registers starting at register firstArg. */ - int dst = (++vPC)->u.operand; - int firstArg = (++vPC)->u.operand; - int argCount = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int firstArg = vPC[2].u.operand; + int argCount = vPC[3].u.operand; ArgList args(callFrame->registers() + firstArg, argCount); callFrame->r(dst) = JSValue(constructArray(callFrame, args)); - ++vPC; + vPC += OPCODE_LENGTH(op_new_array); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_regexp) { @@ -1243,11 +1197,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor from regexp regExp, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int regExp = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int regExp = vPC[2].u.operand; callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp))); - ++vPC; + vPC += OPCODE_LENGTH(op_new_regexp); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mov) { @@ -1255,11 +1209,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Copies register src to register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(src); - ++vPC; + vPC += OPCODE_LENGTH(op_mov); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_eq) { @@ -1269,9 +1223,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi as with the ECMAScript '==' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32()); else { @@ -1280,7 +1234,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_eq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_eq_null) { @@ -1289,17 +1243,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Checks whether register src is null, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isUndefinedOrNull()) { callFrame->r(dst) = jsBoolean(true); - ++vPC; + vPC += OPCODE_LENGTH(op_eq_null); NEXT_INSTRUCTION(); } callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_eq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_neq) { @@ -1309,9 +1263,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi equal, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32()); else { @@ -1320,7 +1274,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_neq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_neq_null) { @@ -1329,17 +1283,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Checks whether register src is not null, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isUndefinedOrNull()) { callFrame->r(dst) = jsBoolean(false); - ++vPC; + vPC += OPCODE_LENGTH(op_neq_null); NEXT_INSTRUCTION(); } callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_neq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_stricteq) { @@ -1349,12 +1303,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi equal, as with the ECMAScript '===' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2)); - ++vPC; + vPC += OPCODE_LENGTH(op_stricteq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_nstricteq) { @@ -1364,12 +1318,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi strictly equal, as with the ECMAScript '!==' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2)); - ++vPC; + vPC += OPCODE_LENGTH(op_nstricteq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_less) { @@ -1379,14 +1333,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi with the ECMAScript '<' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsBoolean(jsLess(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_less); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_lesseq) { @@ -1396,14 +1350,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register src2, as with the ECMAScript '<=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_lesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pre_inc) { @@ -1412,7 +1366,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register srcDst to number, adds one, and puts the result back in register srcDst. */ - int srcDst = (++vPC)->u.operand; + int srcDst = vPC[1].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() < INT_MAX) callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); @@ -1422,7 +1376,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(srcDst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_pre_inc); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pre_dec) { @@ -1431,7 +1385,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register srcDst to number, subtracts one, and puts the result back in register srcDst. */ - int srcDst = (++vPC)->u.operand; + int srcDst = vPC[1].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() > INT_MIN) callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); @@ -1441,7 +1395,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(srcDst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_pre_dec); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_post_inc) { @@ -1451,8 +1405,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi written to register dst, and the number plus one is written back to register srcDst. */ - int dst = (++vPC)->u.operand; - int srcDst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int srcDst = vPC[2].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() < INT_MAX) { callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); @@ -1464,7 +1418,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = number; } - ++vPC; + vPC += OPCODE_LENGTH(op_post_inc); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_post_dec) { @@ -1474,8 +1428,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi written to register dst, and the number minus one is written back to register srcDst. */ - int dst = (++vPC)->u.operand; - int srcDst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int srcDst = vPC[2].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() > INT_MIN) { callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); @@ -1487,7 +1441,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = number; } - ++vPC; + vPC += OPCODE_LENGTH(op_post_dec); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_to_jsnumber) { @@ -1496,8 +1450,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register src to number, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue srcVal = callFrame->r(src).jsValue(); @@ -1509,7 +1463,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_to_jsnumber); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_negate) { @@ -1518,8 +1472,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register src to number, negates it, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isInt32() && src.asInt32()) callFrame->r(dst) = jsNumber(callFrame, -src.asInt32()); else { @@ -1528,7 +1482,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_negate); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_add) { @@ -1538,9 +1492,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. (JS add may be string concatenation or numeric add, depending on the types of the operands.) */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32()); else { @@ -1548,7 +1502,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_add); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mul) { @@ -1557,9 +1511,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Multiplies register src1 and register src2 (converted to numbers), and puts the product in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32()); else { @@ -1568,7 +1522,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_mul); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_div) { @@ -1578,15 +1532,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register divisor (converted to number), and puts the quotient in register dst. */ - int dst = (++vPC)->u.operand; - JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - vPC += 2; + vPC += OPCODE_LENGTH(op_div); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mod) { @@ -1596,15 +1550,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register divisor (converted to number), and puts the remainder in register dst. */ - int dst = (++vPC)->u.operand; - JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) { JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32()); ASSERT(result); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_mod); NEXT_INSTRUCTION(); } @@ -1615,7 +1569,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue result = jsNumber(callFrame, fmod(d1, d2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_mod); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_sub) { @@ -1625,9 +1579,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi src1 (converted to number), and puts the difference in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32()); else { @@ -1635,7 +1589,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_sub); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_lshift) { @@ -1645,9 +1599,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f)); @@ -1657,7 +1611,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_lshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_rshift) { @@ -1667,9 +1621,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi to int32) by register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); @@ -1679,7 +1633,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_rshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_urshift) { @@ -1689,9 +1643,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi to uint32) by register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isUInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); else { @@ -1700,7 +1654,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_urshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitand) { @@ -1710,9 +1664,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32()); else { @@ -1721,7 +1675,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitand); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitxor) { @@ -1731,9 +1685,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32()); else { @@ -1742,7 +1696,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitxor); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitor) { @@ -1752,9 +1706,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32()); else { @@ -1763,7 +1717,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitor); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitnot) { @@ -1772,8 +1726,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Computes bitwise NOT of register src1 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isInt32()) callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32()); else { @@ -1781,7 +1735,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_bitnot); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_not) { @@ -1790,13 +1744,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Computes logical NOT of register src (converted to boolean), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_not); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_instanceof) { @@ -1826,7 +1780,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = jsBoolean(result); - vPC += 5; + vPC += OPCODE_LENGTH(op_instanceof); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_typeof) { @@ -1835,11 +1789,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Determines the type string for src according to ECMAScript rules, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_typeof); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_undefined) { @@ -1849,12 +1803,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "undefined", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue v = callFrame->r(src).jsValue(); callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_undefined); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_boolean) { @@ -1864,11 +1818,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "boolean", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_boolean); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_number) { @@ -1878,11 +1832,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "number", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_number); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_string) { @@ -1892,11 +1846,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "string", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_string); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_object) { @@ -1906,11 +1860,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "object", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_is_object); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_function) { @@ -1920,11 +1874,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "function", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_is_function); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_in) { @@ -1936,9 +1890,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Raises an exception if register constructor is not an object. */ - int dst = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int base = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; + int base = vPC[3].u.operand; JSValue baseVal = callFrame->r(base).jsValue(); if (isInvalidParamForIn(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue)) @@ -1957,7 +1911,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property)); } - ++vPC; + vPC += OPCODE_LENGTH(op_in); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve) { @@ -1970,7 +1924,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 3; + vPC += OPCODE_LENGTH(op_resolve); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_skip) { @@ -1983,7 +1937,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 4; + vPC += OPCODE_LENGTH(op_resolve_skip); NEXT_INSTRUCTION(); } @@ -1998,7 +1952,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 6; + vPC += OPCODE_LENGTH(op_resolve_global); NEXT_INSTRUCTION(); } @@ -2007,13 +1961,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Gets the global var at global slot index and places it in register dst. */ - int dst = (++vPC)->u.operand; - JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); + int dst = vPC[1].u.operand; + JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); ASSERT(scope->isGlobalObject()); - int index = (++vPC)->u.operand; + int index = vPC[3].u.operand; callFrame->r(dst) = scope->registerAt(index); - ++vPC; + vPC += OPCODE_LENGTH(op_get_global_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_global_var) { @@ -2021,13 +1975,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Puts value into global slot index. */ - JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); + JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[1].u.jsCell); ASSERT(scope->isGlobalObject()); - int index = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int index = vPC[2].u.operand; + int value = vPC[3].u.operand; scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_global_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_scoped_var) { @@ -2036,9 +1990,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Loads the contents of the index-th local from the scope skip nodes from the top of the scope chain, and places it in register dst */ - int dst = (++vPC)->u.operand; - int index = (++vPC)->u.operand; - int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain(); + int dst = vPC[1].u.operand; + int index = vPC[2].u.operand; + int skip = vPC[3].u.operand + callFrame->codeBlock()->needsFullScopeChain(); ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -2052,16 +2006,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); callFrame->r(dst) = scope->registerAt(index); - ++vPC; + vPC += OPCODE_LENGTH(op_get_scoped_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_scoped_var) { /* put_scoped_var index(n) skip(n) value(r) */ - int index = (++vPC)->u.operand; - int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain(); - int value = (++vPC)->u.operand; + int index = vPC[1].u.operand; + int skip = vPC[2].u.operand + callFrame->codeBlock()->needsFullScopeChain(); + int value = vPC[3].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -2075,7 +2029,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_scoped_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_base) { @@ -2088,7 +2042,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ resolveBase(callFrame, vPC); - vPC += 3; + vPC += OPCODE_LENGTH(op_resolve_base); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_with_base) { @@ -2106,7 +2060,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 4; + vPC += OPCODE_LENGTH(op_resolve_with_base); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id) { @@ -2129,7 +2083,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot); callFrame->r(dst) = result; - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_self) { @@ -2155,7 +2109,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_self); NEXT_INSTRUCTION(); } } @@ -2187,9 +2141,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int offset = vPC[6].u.operand; ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); + ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_proto); NEXT_INSTRUCTION(); } } @@ -2202,14 +2157,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi // Polymorphic self access caching currently only supported when JITting. ASSERT_NOT_REACHED(); // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_self_list); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_proto_list) { // Polymorphic prototype access caching currently only supported when JITting. ASSERT_NOT_REACHED(); // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_proto_list); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_chain) { @@ -2242,9 +2197,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int offset = vPC[7].u.operand; ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); + ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_chain); NEXT_INSTRUCTION(); } @@ -2274,7 +2230,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_generic); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_array_length) { @@ -2290,7 +2246,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (LIKELY(isJSArray(globalData, baseValue))) { int dst = vPC[1].u.operand; callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length()); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_array_length); NEXT_INSTRUCTION(); } @@ -2310,7 +2266,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (LIKELY(isJSString(globalData, baseValue))) { int dst = vPC[1].u.operand; callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size()); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_string_length); NEXT_INSTRUCTION(); } @@ -2340,7 +2296,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_id_transition) { @@ -2385,7 +2341,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_transition); NEXT_INSTRUCTION(); } } @@ -2420,7 +2376,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_replace); NEXT_INSTRUCTION(); } } @@ -2447,7 +2403,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); CHECK_FOR_EXCEPTION(); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_generic); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_del_by_id) { @@ -2458,16 +2414,43 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi boolean indicating success (if true) or failure (if false) to register dst. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); Identifier& ident = callFrame->codeBlock()->identifier(property); JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_del_by_id); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(op_get_by_pname) { + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; + int expected = vPC[4].u.operand; + int iter = vPC[5].u.operand; + int i = vPC[6].u.operand; + + JSValue baseValue = callFrame->r(base).jsValue(); + JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); + JSValue subscript = callFrame->r(property).jsValue(); + JSValue expectedSubscript = callFrame->r(expected).jsValue(); + int index = callFrame->r(i).i() - 1; + JSValue result; + int offset = 0; + if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { + callFrame->r(dst) = asObject(baseValue)->getDirectOffset(offset); + vPC += OPCODE_LENGTH(op_get_by_pname); + NEXT_INSTRUCTION(); + } + Identifier propertyName(callFrame, subscript.toString(callFrame)); + result = baseValue.get(callFrame, propertyName); + CHECK_FOR_EXCEPTION(); + callFrame->r(dst) = result; + vPC += OPCODE_LENGTH(op_get_by_pname); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_val) { @@ -2478,9 +2461,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. property is nominally converted to string but numbers are treated more efficiently. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSValue baseValue = callFrame->r(base).jsValue(); JSValue subscript = callFrame->r(property).jsValue(); @@ -2508,7 +2491,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_get_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_val) { @@ -2522,9 +2505,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int value = vPC[3].u.operand; JSValue baseValue = callFrame->r(base).jsValue(); JSValue subscript = callFrame->r(property).jsValue(); @@ -2558,7 +2541,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - ++vPC; + vPC += OPCODE_LENGTH(op_put_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_del_by_val) { @@ -2569,9 +2552,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi boolean indicating success (if true) or failure (if false) to register dst. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw @@ -2589,7 +2572,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_del_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_index) { @@ -2604,13 +2587,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi This opcode is mainly used to initialize array literals. */ - int base = (++vPC)->u.operand; - unsigned property = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int base = vPC[1].u.operand; + unsigned property = vPC[2].u.operand; + int value = vPC[3].u.operand; callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_by_index); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop) { @@ -2625,7 +2608,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi #if ENABLE(OPCODE_STATS) OpcodeStats::resetLastInstruction(); #endif - int target = (++vPC)->u.operand; + int target = vPC[1].u.operand; CHECK_FOR_TIMEOUT(); vPC += target; NEXT_INSTRUCTION(); @@ -2639,7 +2622,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi #if ENABLE(OPCODE_STATS) OpcodeStats::resetLastInstruction(); #endif - int target = (++vPC)->u.operand; + int target = vPC[1].u.operand; vPC += target; NEXT_INSTRUCTION(); @@ -2653,15 +2636,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; CHECK_FOR_TIMEOUT(); NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_true); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jtrue) { @@ -2670,14 +2653,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register cond converts to boolean as true. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jtrue); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jfalse) { @@ -2686,14 +2669,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register cond converts to boolean as false. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jfalse); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jeq_null) { @@ -2702,8 +2685,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register src is null. */ - int src = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + int target = vPC[2].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { @@ -2711,7 +2694,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jeq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jneq_null) { @@ -2720,8 +2703,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register src is not null. */ - int src = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + int target = vPC[2].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { @@ -2729,7 +2712,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jneq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jneq_ptr) { @@ -2738,16 +2721,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if the value r is equal to ptr, using pointer equality. */ - int src = (++vPC)->u.operand; - JSValue ptr = JSValue((++vPC)->u.jsCell); - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + JSValue ptr = JSValue(vPC[2].u.jsCell); + int target = vPC[3].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue != ptr) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jneq_ptr); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop_if_less) { @@ -2761,9 +2744,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2774,7 +2757,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_less); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop_if_lesseq) { @@ -2788,9 +2771,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLessEq(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2801,7 +2784,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_lesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jnless) { @@ -2812,9 +2795,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi target from the current instruction, if and only if the result of the comparison is false. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2824,7 +2807,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jnless); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jnlesseq) { @@ -2835,9 +2818,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and then jumps to offset target from the current instruction, if and only if theresult of the comparison is false. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLessEq(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2847,7 +2830,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jnlesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_switch_imm) { @@ -2859,9 +2842,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi table, and the value at jumpTable[scrutinee value] is non-zero, then that value is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (scrutinee.isInt32()) vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); else { @@ -2883,9 +2866,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi table, and the value at jumpTable[scrutinee value] is non-zero, then that value is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else { @@ -2906,9 +2889,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi jump table, then the value associated with the string is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else @@ -2923,12 +2906,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor, using the rules for function declarations, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int func = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int func = vPC[2].u.operand; callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain())); - ++vPC; + vPC += OPCODE_LENGTH(op_new_func); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_func_exp) { @@ -2939,8 +2922,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor, using the rules for function expressions, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int funcIndex = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int funcIndex = vPC[2].u.operand; FunctionExecutable* function = callFrame->codeBlock()->functionExpr(funcIndex); JSFunction* func = function->make(callFrame, callFrame->scopeChain()); @@ -2959,7 +2942,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = JSValue(func); - ++vPC; + vPC += OPCODE_LENGTH(op_new_func_exp); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_call_eval) { @@ -2992,7 +2975,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi goto vm_throw; callFrame->r(dst) = result; - vPC += 5; + vPC += OPCODE_LENGTH(op_call_eval); NEXT_INSTRUCTION(); } @@ -3066,7 +3049,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call); NEXT_INSTRUCTION(); } @@ -3076,8 +3059,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi goto vm_throw; } DEFINE_OPCODE(op_load_varargs) { - int argCountDst = (++vPC)->u.operand; - int argsOffset = (++vPC)->u.operand; + int argCountDst = vPC[1].u.operand; + int argsOffset = vPC[2].u.operand; JSValue arguments = callFrame->r(argsOffset).jsValue(); int32_t argCount = 0; @@ -3149,7 +3132,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); callFrame->r(argCountDst) = Register::withInt(argCount + 1); - ++vPC; + vPC += OPCODE_LENGTH(op_load_varargs); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_call_varargs) { @@ -3220,7 +3203,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call_varargs); NEXT_INSTRUCTION(); } @@ -3242,12 +3225,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi This opcode should only be used immediately before op_ret. */ - int src = (++vPC)->u.operand; + int src = vPC[1].u.operand; ASSERT(callFrame->codeBlock()->needsFullScopeChain()); asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments()); - ++vPC; + vPC += OPCODE_LENGTH(op_tear_off_activation); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_tear_off_arguments) { @@ -3268,7 +3251,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callFrame->optionalCalleeArguments()) callFrame->optionalCalleeArguments()->copyRegisters(); - ++vPC; + vPC += OPCODE_LENGTH(op_tear_off_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_ret) { @@ -3281,7 +3264,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register base to those of the calling function. */ - int result = (++vPC)->u.operand; + int result = vPC[1].u.operand; if (callFrame->codeBlock()->needsFullScopeChain()) callFrame->scopeChain()->deref(); @@ -3316,7 +3299,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi for (size_t count = codeBlock->m_numVars; i < count; ++i) callFrame->r(i) = jsUndefined(); - ++vPC; + vPC += OPCODE_LENGTH(op_enter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_enter_with_activation) { @@ -3338,12 +3321,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi for (size_t count = codeBlock->m_numVars; i < count; ++i) callFrame->r(i) = jsUndefined(); - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable())); callFrame->r(dst) = JSValue(activation); callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); - ++vPC; + vPC += OPCODE_LENGTH(op_enter_with_activation); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_convert_this) { @@ -3358,12 +3341,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi block. */ - int thisRegister = (++vPC)->u.operand; + int thisRegister = vPC[1].u.operand; JSValue thisVal = callFrame->r(thisRegister).jsValue(); if (thisVal.needsThisConversion()) callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); - ++vPC; + vPC += OPCODE_LENGTH(op_convert_this); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_init_arguments) { @@ -3377,7 +3360,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi block. */ callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(); - ++vPC; + vPC += OPCODE_LENGTH(op_init_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_create_arguments) { @@ -3393,7 +3376,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->setCalleeArguments(arguments); callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } - ++vPC; + vPC += OPCODE_LENGTH(op_create_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_construct) { @@ -3471,7 +3454,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = JSValue(returnValue); - vPC += 7; + vPC += OPCODE_LENGTH(op_construct); NEXT_INSTRUCTION(); } @@ -3489,32 +3472,32 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = vPC[1].u.operand; if (LIKELY(callFrame->r(dst).jsValue().isObject())) { - vPC += 3; + vPC += OPCODE_LENGTH(op_construct_verify); NEXT_INSTRUCTION(); } int override = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(override); - vPC += 3; + vPC += OPCODE_LENGTH(op_construct_verify); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_strcat) { - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; - int count = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; + int count = vPC[3].u.operand; callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count); - ++vPC; + vPC += OPCODE_LENGTH(op_strcat); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_to_primitive) { - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame); - ++vPC; + vPC += OPCODE_LENGTH(op_to_primitive); NEXT_INSTRUCTION(); } @@ -3525,7 +3508,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi of the current scope chain. The contents of the register scope are replaced by the result of toObject conversion of the scope. */ - int scope = (++vPC)->u.operand; + int scope = vPC[1].u.operand; JSValue v = callFrame->r(scope).jsValue(); JSObject* o = v.toObject(callFrame); CHECK_FOR_EXCEPTION(); @@ -3533,7 +3516,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(scope) = JSValue(o); callFrame->setScopeChain(callFrame->scopeChain()->push(o)); - ++vPC; + vPC += OPCODE_LENGTH(op_push_scope); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pop_scope) { @@ -3543,47 +3526,69 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ callFrame->setScopeChain(callFrame->scopeChain()->pop()); - ++vPC; + vPC += OPCODE_LENGTH(op_pop_scope); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_pnames) { - /* get_pnames dst(r) base(r) + /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset) Creates a property name list for register base and puts it - in register dst. This is not a true JavaScript value, just - a synthetic value used to keep the iteration state in a - register. + in register dst, initializing i and size for iteration. If + base is undefined or null, jumps to breakTarget. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int breakTarget = vPC[5].u.operand; - callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue()); - ++vPC; + JSValue v = callFrame->r(base).jsValue(); + if (v.isUndefinedOrNull()) { + vPC += breakTarget; + NEXT_INSTRUCTION(); + } + + JSObject* o = v.toObject(callFrame); + Structure* structure = o->structure(); + JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); + if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) + jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); + + callFrame->r(dst) = jsPropertyNameIterator; + callFrame->r(base) = JSValue(o); + callFrame->r(i) = Register::withInt(0); + callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size()); + vPC += OPCODE_LENGTH(op_get_pnames); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_next_pname) { - /* next_pname dst(r) iter(r) target(offset) + /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) - Tries to copies the next name from property name list in - register iter. If there are names left, then copies one to - register dst, and jumps to offset target. If there are none - left, invalidates the iterator and continues to the next + Copies the next name from the property name list in + register iter to dst, then jumps to offset target. If there are no + names left, invalidates the iterator and continues to the next instruction. */ - int dst = (++vPC)->u.operand; - int iter = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int iter = vPC[5].u.operand; + int target = vPC[6].u.operand; JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); - if (JSValue temp = it->next(callFrame)) { - CHECK_FOR_TIMEOUT(); - callFrame->r(dst) = JSValue(temp); - vPC += target; - NEXT_INSTRUCTION(); + while (callFrame->r(i).i() != callFrame->r(size).i()) { + JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); + callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1); + if (key) { + CHECK_FOR_TIMEOUT(); + callFrame->r(dst) = key; + vPC += target; + NEXT_INSTRUCTION(); + } } - it->invalidate(); - ++vPC; + vPC += OPCODE_LENGTH(op_next_pname); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jmp_scopes) { @@ -3593,8 +3598,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi specified by immediate number count, then jumps to offset target. */ - int count = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int count = vPC[1].u.operand; + int target = vPC[2].u.operand; ScopeChainNode* tmp = callFrame->scopeChain(); while (count--) @@ -3617,7 +3622,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ callFrame->setScopeChain(createExceptionScope(callFrame, vPC)); - vPC += 4; + vPC += OPCODE_LENGTH(op_push_new_scope); NEXT_INSTRUCTION(); } #if HAVE(COMPUTED_GOTO) @@ -3632,11 +3637,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ ASSERT(exceptionValue); ASSERT(!globalData->exception); - int ex = (++vPC)->u.operand; + int ex = vPC[1].u.operand; callFrame->r(ex) = exceptionValue; exceptionValue = JSValue(); - ++vPC; + vPC += OPCODE_LENGTH(op_catch); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_throw) { @@ -3650,7 +3655,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi else the script returns control to the nearest native caller. */ - int ex = (++vPC)->u.operand; + int ex = vPC[1].u.operand; exceptionValue = callFrame->r(ex).jsValue(); handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true); @@ -3670,14 +3675,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constant message as the message string. The result is written to register dst. */ - int dst = (++vPC)->u.operand; - int type = (++vPC)->u.operand; - int message = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int type = vPC[2].u.operand; + int message = vPC[3].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL())); - ++vPC; + vPC += OPCODE_LENGTH(op_new_error); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_end) { @@ -3692,7 +3697,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(scopeChain->refCount > 1); scopeChain->deref(); } - int result = (++vPC)->u.operand; + int result = vPC[1].u.operand; return callFrame->r(result).jsValue(); } DEFINE_OPCODE(op_put_getter) { @@ -3706,9 +3711,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int function = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int function = vPC[3].u.operand; ASSERT(callFrame->r(base).jsValue().isObject()); JSObject* baseObj = asObject(callFrame->r(base).jsValue()); @@ -3716,7 +3721,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(callFrame->r(function).jsValue().isObject()); baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_put_getter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_setter) { @@ -3730,9 +3735,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int function = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int function = vPC[3].u.operand; ASSERT(callFrame->r(base).jsValue().isObject()); JSObject* baseObj = asObject(callFrame->r(base).jsValue()); @@ -3740,7 +3745,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(callFrame->r(function).jsValue().isObject()); baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); - ++vPC; + vPC += OPCODE_LENGTH(op_put_setter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_method_check) { @@ -3753,9 +3758,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Places the address of the next instruction into the retAddrDst register and jumps to offset target from the current instruction. */ - int retAddrDst = (++vPC)->u.operand; - int target = (++vPC)->u.operand; - callFrame->r(retAddrDst) = vPC + 1; + int retAddrDst = vPC[1].u.operand; + int target = vPC[2].u.operand; + callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr); vPC += target; NEXT_INSTRUCTION(); @@ -3767,7 +3772,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi differs from op_jmp because the target address is stored in a register, not as an immediate. */ - int retAddrSrc = (++vPC)->u.operand; + int retAddrSrc = vPC[1].u.operand; vPC = callFrame->r(retAddrSrc).vPC(); NEXT_INSTRUCTION(); } @@ -3777,13 +3782,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Notifies the debugger of the current state of execution. This opcode is only generated while the debugger is attached. */ - int debugHookID = (++vPC)->u.operand; - int firstLine = (++vPC)->u.operand; - int lastLine = (++vPC)->u.operand; + int debugHookID = vPC[1].u.operand; + int firstLine = vPC[2].u.operand; + int lastLine = vPC[3].u.operand; debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine); - ++vPC; + vPC += OPCODE_LENGTH(op_debug); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_profile_will_call) { @@ -3797,7 +3802,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (*enabledProfilerReference) (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue()); - vPC += 2; + vPC += OPCODE_LENGTH(op_profile_will_call); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_profile_did_call) { @@ -3811,7 +3816,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (*enabledProfilerReference) (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue()); - vPC += 2; + vPC += OPCODE_LENGTH(op_profile_did_call); NEXT_INSTRUCTION(); } vm_throw: { diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h index 3046b28b38..e17b055d12 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h @@ -129,7 +129,6 @@ namespace JSC { NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue); NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC); NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue); - NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue& exceptionValue); NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC); void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 3274fcc676..5c43eebcf0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -78,6 +78,9 @@ private: struct Allocation { char* pages; size_t size; +#if PLATFORM(SYMBIAN) + RChunk* chunk; +#endif }; typedef Vector<Allocation, 2> AllocationList; @@ -186,6 +189,22 @@ public: sys_dcache_flush(code, size); sys_icache_invalidate(code, size); } +#elif PLATFORM(ARM_THUMB2) && PLATFORM(LINUX) + static void cacheFlush(void* code, size_t size) + { + asm volatile ( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "movw r7, #0x2\n" + "movt r7, #0xf\n" + "movs r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (code), "r" (reinterpret_cast<char*>(code) + size) + : "r0", "r1"); + } #elif PLATFORM(SYMBIAN) static void cacheFlush(void* code, size_t size) { diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp new file mode 100644 index 0000000000..c96ecae3b7 --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp @@ -0,0 +1,75 @@ +/* + * 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(ASSEMBLER) && PLATFORM(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 PLATFORM_ARM_ARCH(5) + // 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; +} + +#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) +#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." +#endif + +} + +#endif // HAVE(ASSEMBLER) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp index ea8434ebb9..000e4b8214 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp @@ -202,7 +202,6 @@ void JIT::privateCompileMainPass() DEFINE_BINARY_OP(op_less) DEFINE_BINARY_OP(op_lesseq) DEFINE_BINARY_OP(op_urshift) - DEFINE_UNARY_OP(op_get_pnames) DEFINE_UNARY_OP(op_is_boolean) DEFINE_UNARY_OP(op_is_function) DEFINE_UNARY_OP(op_is_number) @@ -240,7 +239,9 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_eq_null) DEFINE_OP(op_get_by_id) DEFINE_OP(op_get_by_val) + DEFINE_OP(op_get_by_pname) DEFINE_OP(op_get_global_var) + DEFINE_OP(op_get_pnames) DEFINE_OP(op_get_scoped_var) DEFINE_OP(op_instanceof) DEFINE_OP(op_jeq_null) @@ -385,6 +386,7 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_eq) DEFINE_SLOWCASE_OP(op_get_by_id) DEFINE_SLOWCASE_OP(op_get_by_val) + DEFINE_SLOWCASE_OP(op_get_by_pname) DEFINE_SLOWCASE_OP(op_instanceof) DEFINE_SLOWCASE_OP(op_jfalse) DEFINE_SLOWCASE_OP(op_jnless) @@ -489,21 +491,21 @@ JITCode JIT::privateCompile() ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character); ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size()); - record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) { unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j]; - record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; + record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; } } else { ASSERT(record.type == SwitchRecord::String); - record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end(); for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) { unsigned offset = it->second.branchOffset; - it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault; + it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.stringJumpTable->ctiDefault; } } } diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h index 0712743f19..e19ea1750c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h @@ -38,6 +38,8 @@ #define JIT_CLASS_ALIGNMENT #endif +#define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(actual), static_cast<int>(expected)); + #include "CodeBlock.h" #include "Interpreter.h" #include "JITCode.h" @@ -249,7 +251,6 @@ namespace JSC { static const RegisterID timeoutCheckRegister = ARMRegisters::r5; static const RegisterID callFrameRegister = ARMRegisters::r4; - static const RegisterID ctiReturnRegister = ARMRegisters::r6; static const RegisterID regT0 = ARMRegisters::r0; static const RegisterID regT1 = ARMRegisters::r1; @@ -386,6 +387,8 @@ namespace JSC { Address addressFor(unsigned index, RegisterID base = callFrameRegister); + void testPrototype(Structure*, JumpList& failureCases); + #if USE(JSVALUE32_64) Address tagFor(unsigned index, RegisterID base = callFrameRegister); Address payloadFor(unsigned index, RegisterID base = callFrameRegister); @@ -425,6 +428,7 @@ namespace JSC { #endif void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset); void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); // Arithmetic opcode helpers @@ -526,6 +530,7 @@ namespace JSC { #endif void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); #if PLATFORM(X86_64) @@ -581,26 +586,26 @@ namespace JSC { #elif PLATFORM(ARM_THUMB2) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 10; - static const int patchOffsetPutByIdExternalLoad = 20; + static const int patchOffsetPutByIdExternalLoad = 26; static const int patchLengthPutByIdExternalLoad = 12; - static const int patchOffsetPutByIdPropertyMapOffset = 40; + static const int patchOffsetPutByIdPropertyMapOffset = 46; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 10; - static const int patchOffsetGetByIdBranchToSlowCase = 20; - static const int patchOffsetGetByIdExternalLoad = 20; + static const int patchOffsetGetByIdBranchToSlowCase = 26; + static const int patchOffsetGetByIdExternalLoad = 26; static const int patchLengthGetByIdExternalLoad = 12; - static const int patchOffsetGetByIdPropertyMapOffset = 40; - static const int patchOffsetGetByIdPutResult = 44; + static const int patchOffsetGetByIdPropertyMapOffset = 46; + static const int patchOffsetGetByIdPutResult = 50; #if ENABLE(OPCODE_SAMPLING) static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE #else static const int patchOffsetGetByIdSlowCaseCall = 28; #endif - static const int patchOffsetOpCallCompareToJump = 10; + static const int patchOffsetOpCallCompareToJump = 16; - static const int patchOffsetMethodCheckProtoObj = 18; - static const int patchOffsetMethodCheckProtoStruct = 28; - static const int patchOffsetMethodCheckPutFunction = 46; + static const int patchOffsetMethodCheckProtoObj = 24; + static const int patchOffsetMethodCheckProtoStruct = 34; + static const int patchOffsetMethodCheckPutFunction = 58; #elif PLATFORM(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; @@ -617,7 +622,7 @@ namespace JSC { #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else - static const int patchOffsetGetByIdSlowCaseCall = 36; + static const int patchOffsetGetByIdSlowCaseCall = 28; #endif static const int patchOffsetOpCallCompareToJump = 12; @@ -638,7 +643,7 @@ namespace JSC { static const int sequenceGetByIdHotPathInstructionSpace = 28; static const int sequenceGetByIdHotPathConstantSpace = 3; // sequenceGetByIdSlowCase - static const int sequenceGetByIdSlowCaseInstructionSpace = 40; + static const int sequenceGetByIdSlowCaseInstructionSpace = 32; static const int sequenceGetByIdSlowCaseConstantSpace = 2; // sequencePutById static const int sequencePutByIdInstructionSpace = 28; @@ -680,6 +685,7 @@ namespace JSC { void emit_op_eq_null(Instruction*); void emit_op_get_by_id(Instruction*); void emit_op_get_by_val(Instruction*); + void emit_op_get_by_pname(Instruction*); void emit_op_get_global_var(Instruction*); void emit_op_get_scoped_var(Instruction*); void emit_op_init_arguments(Instruction*); @@ -713,6 +719,7 @@ namespace JSC { void emit_op_new_func_exp(Instruction*); void emit_op_new_object(Instruction*); void emit_op_new_regexp(Instruction*); + void emit_op_get_pnames(Instruction*); void emit_op_next_pname(Instruction*); void emit_op_not(Instruction*); void emit_op_nstricteq(Instruction*); @@ -768,6 +775,7 @@ namespace JSC { void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp index 7afc1f2559..8cda482040 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp @@ -98,16 +98,16 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT3, regT2); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target); } else if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); } else { emitLoad2(op1, regT1, regT0, op2, regT3, regT2); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, regT2), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, regT2), target); } if (!supportsFloatingPoint()) { @@ -145,7 +145,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } void JIT::emit_op_jnlesseq(Instruction* currentInstruction) @@ -161,16 +161,16 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT3, regT2); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target); } else if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); } else { emitLoad2(op1, regT1, regT0, op2, regT3, regT2); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, regT2), target + 3); + addJump(branch32(GreaterThan, regT0, regT2), target); } if (!supportsFloatingPoint()) { @@ -208,7 +208,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } // LeftShift (<<) @@ -829,11 +829,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi break; case op_jnless: emitLoadDouble(op1, fpRegT2); - addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst + 3); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst); break; case op_jnlesseq: emitLoadDouble(op1, fpRegT2); - addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst + 3); + addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst); break; default: ASSERT_NOT_REACHED(); @@ -882,11 +882,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi break; case op_jnless: emitLoadDouble(op2, fpRegT1); - addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst + 3); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst); break; case op_jnlesseq: emitLoadDouble(op2, fpRegT1); - addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst + 3); + addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst); break; default: ASSERT_NOT_REACHED(); @@ -1313,7 +1313,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -1322,13 +1322,13 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target + 3); + addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, regT1), target); } } @@ -1365,7 +1365,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1382,7 +1382,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); @@ -1406,7 +1406,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1423,7 +1423,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else { linkSlowCase(iter); @@ -1452,7 +1452,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1475,7 +1475,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } } @@ -1498,7 +1498,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -1507,13 +1507,13 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(LessThan, regT1, Imm32(op1imm)), target + 3); + addJump(branch32(LessThan, regT1, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(GreaterThan, regT0, regT1), target + 3); + addJump(branch32(GreaterThan, regT0, regT1), target); } } @@ -1550,7 +1550,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1567,7 +1567,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); @@ -1591,7 +1591,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1608,7 +1608,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else { linkSlowCase(iter); @@ -1637,7 +1637,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1660,7 +1660,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp index 4fd24d2c3e..f7fcc0a6e2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp @@ -236,19 +236,17 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); } - emitLoad(callee, regT1, regT2); + emitLoad(callee, regT1, regT0); if (opcodeID == op_call) compileOpCallSetupArgs(instruction); @@ -256,12 +254,12 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) compileOpConstructSetupArgs(instruction); emitJumpSlowCaseIfNotJSCell(callee, regT1); - addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr))); + addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); // First, in the case of a construct, allocate the new object. if (opcodeID == op_construct) { JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); - emitLoad(callee, regT1, regT2); + emitLoad(callee, regT1, regT0); } // Speculatively roll the callframe, assuming argCount will match the arity. @@ -271,12 +269,10 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); - emitStore(dst, regT1, regT0);; + emitStore(dst, regT1, regT0); sampleCodeBlock(m_codeBlock); } @@ -306,16 +302,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); } emitLoad(callee, regT1, regT0); @@ -359,10 +353,8 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Call to the callee m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); // Put the return value in dst. In the interpreter, op_ret does this. emitStore(dst, regT1, regT0); @@ -622,7 +614,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca END_UNINTERRUPTED_SEQUENCE(sequenceOpCall); addSlowCase(jumpToSlow); - ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump); + ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; // The following is the fast case, only used whan a callee can be linked. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h index f26457ab0f..93d6ce76ed 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h @@ -144,7 +144,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) #endif -#if PLATFORM(ARM_THUMB2) +#if PLATFORM(ARM) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -161,7 +161,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) loadPtr(address, linkRegister); } -#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL) +#else // PLATFORM(X86) || PLATFORM(X86_64) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -191,16 +191,13 @@ ALWAYS_INLINE void JIT::restoreArgumentReference() { move(stackPointerRegister, firstArgumentRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); -#if PLATFORM(ARM_TRADITIONAL) - move(ctiReturnRegister, ARMRegisters::lr); -#endif } ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() { #if PLATFORM(X86) // Within a trampoline the return address will be on the stack at this point. addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister); -#elif PLATFORM(ARM_THUMB2) +#elif PLATFORM(ARM) move(stackPointerRegister, firstArgumentRegister); #endif // In the trampoline on x86-64, the first argument register is not overwritten. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp index 7059cc8930..14736cfb80 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp @@ -33,6 +33,7 @@ #include "JSArray.h" #include "JSCell.h" #include "JSFunction.h" +#include "JSPropertyNameIterator.h" #include "LinkBuffer.h" namespace JSC { @@ -248,10 +249,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); // Check for an exception - // FIXME: Maybe we can optimize this comparison to JSValue(). move(ImmPtr(&globalData->exception), regT2); - Jump sawException1 = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::CellTag)); - Jump sawException2 = branch32(NonZero, payloadFor(0, regT2), Imm32(0)); + Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag)); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3); @@ -264,13 +263,12 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable ret(); // Handle an exception - sawException1.link(this); - sawException2.link(this); + sawException.link(this); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); restoreReturnAddressBeforeReturn(regT2); @@ -348,14 +346,14 @@ void JIT::emit_op_end(Instruction* currentInstruction) void JIT::emit_op_jmp(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; emitTimeoutCheck(); - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop_if_less(Instruction* currentInstruction) @@ -369,21 +367,21 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target); return; } if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); return; } emitLoad2(op1, regT1, regT0, op2, regT3, regT2); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, regT2), target + 3); + addJump(branch32(LessThan, regT0, regT2), target); } void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -400,7 +398,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) @@ -414,21 +412,21 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target); return; } if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); return; } emitLoad2(op1, regT1, regT0, op2, regT3, regT2); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT0, regT2), target + 3); + addJump(branch32(LessThanOrEqual, regT0, regT2), target); } void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -445,7 +443,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_new_object(Instruction* currentInstruction) @@ -460,30 +458,20 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) unsigned baseVal = currentInstruction[3].u.operand; unsigned proto = currentInstruction[4].u.operand; - // Load the operands (baseVal, proto, and value respectively) into registers. + // Load the operands into registers. // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. - emitLoadPayload(proto, regT1); - emitLoadPayload(baseVal, regT0); emitLoadPayload(value, regT2); + emitLoadPayload(baseVal, regT0); + emitLoadPayload(proto, regT1); - // Check that baseVal & proto are cells. - emitJumpSlowCaseIfNotJSCell(proto); + // Check that value, baseVal, and proto are cells. + emitJumpSlowCaseIfNotJSCell(value); emitJumpSlowCaseIfNotJSCell(baseVal); + emitJumpSlowCaseIfNotJSCell(proto); - // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + // Check that baseVal 'ImplementsDefaultHasInstance'. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); // FIXME: Maybe remove this test. - addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance))); // FIXME: TOT checks ImplementsDefaultHasInstance. - - // If value is not an Object, return false. - emitLoadTag(value, regT0); - Jump valueIsImmediate = branch32(NotEqual, regT0, Imm32(JSValue::CellTag)); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); // FIXME: Maybe remove this test. - - // Check proto is object. - loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance))); // Optimistically load the result true, and start looping. // Initially, regT1 still contains proto and regT2 still contains value. @@ -491,16 +479,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) move(Imm32(JSValue::TrueTag), regT0); Label loop(this); - // Load the prototype of the object in regT2. If this is equal to regT1 - WIN! + // Load the prototype of the cell in regT2. If this is equal to regT1 - WIN! // Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again. loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2); Jump isInstance = branchPtr(Equal, regT2, regT1); - branch32(NotEqual, regT2, Imm32(0), loop); + branchTest32(NonZero, regT2).linkTo(loop, this); // We get here either by dropping out of the loop, or if value was not an Object. Result is false. - valueIsImmediate.link(this); - valueIsNotObject.link(this); move(Imm32(JSValue::FalseTag), regT0); // isInstance jumps right down to here, to skip setting the result to false (it has already set true). @@ -515,11 +501,10 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas unsigned baseVal = currentInstruction[3].u.operand; unsigned proto = currentInstruction[4].u.operand; + linkSlowCaseIfNotJSCell(iter, value); linkSlowCaseIfNotJSCell(iter, baseVal); linkSlowCaseIfNotJSCell(iter, proto); linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); JITStubCall stubCall(this, cti_op_instanceof); stubCall.addArgument(value); @@ -674,12 +659,12 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); - addJump(branch32(NotEqual, regT0, Imm32(0)), target + 2); + addJump(branch32(NotEqual, regT0, Imm32(0)), target); Jump isNotZero = jump(); isNotInteger.link(this); - addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag))); isNotZero.link(this); @@ -695,7 +680,7 @@ void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowC JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_resolve_base(Instruction* currentInstruction) @@ -788,11 +773,11 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag)); - addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0)); - addJump(jump(), target + 2); + addJump(jump(), target); if (supportsFloatingPoint()) { isNotInteger.link(this); @@ -801,7 +786,7 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) zeroDouble(fpRegT0); emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2); + addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target); } else addSlowCase(isNotInteger); @@ -818,7 +803,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // Inverted. + emitJumpSlowToHot(branchTest32(Zero, regT0), target); // Inverted. } void JIT::emit_op_jtrue(Instruction* currentInstruction) @@ -829,11 +814,11 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag)); - addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); Jump isFalse2 = branch32(Equal, regT0, Imm32(0)); - addJump(jump(), target + 2); + addJump(jump(), target); if (supportsFloatingPoint()) { isNotInteger.link(this); @@ -842,7 +827,7 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) zeroDouble(fpRegT0); emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2); + addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target); } else addSlowCase(isNotInteger); @@ -859,7 +844,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_jeq_null(Instruction* currentInstruction) @@ -873,7 +858,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); @@ -884,7 +869,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); or32(regT2, regT1); - addJump(branchTest32(NonZero, regT1), target + 2); + addJump(branchTest32(NonZero, regT1), target); wasNotImmediate.link(this); } @@ -900,7 +885,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); @@ -911,7 +896,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); or32(regT2, regT1); - addJump(branchTest32(Zero, regT1), target + 2); + addJump(branchTest32(Zero, regT1), target); wasNotImmediate.link(this); } @@ -923,8 +908,8 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) unsigned target = currentInstruction[3].u.operand; emitLoad(src, regT1, regT0); - addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target + 3); - addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target + 3); + addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target); + addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target); } void JIT::emit_op_jsr(Instruction* currentInstruction) @@ -932,7 +917,7 @@ void JIT::emit_op_jsr(Instruction* currentInstruction) int retAddrDst = currentInstruction[1].u.operand; int target = currentInstruction[2].u.operand; DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst)); - addJump(jump(), target + 2); + addJump(jump(), target); m_jsrSites.append(JSRInfo(storeLocation, label())); } @@ -1198,23 +1183,109 @@ void JIT::emit_op_throw(Instruction* currentInstruction) #endif } +void JIT::emit_op_get_pnames(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int breakTarget = currentInstruction[5].u.operand; + + JumpList isNotObject; + + emitLoad(base, regT1, regT0); + if (!m_codeBlock->isKnownNotImmediate(base)) + isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); + if (base != m_codeBlock->thisRegister()) { + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + } + + // We could inline the case where you have a valid cache, but + // this call doesn't seem to be hot. + Label isObject(this); + JITStubCall getPnamesStubCall(this, cti_op_get_pnames); + getPnamesStubCall.addArgument(regT0); + getPnamesStubCall.call(dst); + load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3); + store32(Imm32(0), addressFor(i)); + store32(regT3, addressFor(size)); + Jump end = jump(); + + isNotObject.link(this); + addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget); + addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget); + JITStubCall toObjectStubCall(this, cti_to_object); + toObjectStubCall.addArgument(regT1, regT0); + toObjectStubCall.call(base); + jump().linkTo(isObject, this); + + end.link(this); +} + void JIT::emit_op_next_pname(Instruction* currentInstruction) { int dst = currentInstruction[1].u.operand; - int iter = currentInstruction[2].u.operand; - int target = currentInstruction[3].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int it = currentInstruction[5].u.operand; + int target = currentInstruction[6].u.operand; + + JumpList callHasProperty; + + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); + + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + load32(BaseIndex(regT2, regT0, TimesEight), regT2); + store32(Imm32(JSValue::CellTag), tagFor(dst)); + store32(regT2, payloadFor(dst)); + + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + loadPtr(addressFor(base), regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); - load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0); + // Test base's prototype chain + loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3); + loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3); + addJump(branchTestPtr(Zero, Address(regT3)), target); - JITStubCall stubCall(this, cti_op_next_pname); + Label checkPrototype(this); + callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag))); + loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3))); + addPtr(Imm32(sizeof(Structure*)), regT3); + branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this); + + // Continue loop. + addJump(jump(), target); + + // Slow case: Ask the object if i is valid. + callHasProperty.link(this); + loadPtr(addressFor(dst), regT1); + JITStubCall stubCall(this, cti_has_property); stubCall.addArgument(regT0); + stubCall.addArgument(regT1); stubCall.call(); - Jump endOfIter = branchTestPtr(Zero, regT0); - emitStore(dst, regT1, regT0); - map(m_bytecodeIndex + OPCODE_LENGTH(op_next_pname), dst, regT1, regT0); - addJump(jump(), target + 3); - endOfIter.link(this); + // Test for valid key. + addJump(branchTest32(NonZero, regT0), target); + jump().linkTo(begin, this); + + // End of loop. + end.link(this); } void JIT::emit_op_push_scope(Instruction* currentInstruction) @@ -1237,7 +1308,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction) emitLoad(src, regT1, regT0); Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag)); - addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag))); + addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::EmptyValueTag))); isInt32.link(this); if (src != dst) @@ -1284,7 +1355,7 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); - addJump(jump(), currentInstruction[2].u.operand + 2); + addJump(jump(), currentInstruction[2].u.operand); } void JIT::emit_op_switch_imm(Instruction* currentInstruction) @@ -1381,8 +1452,7 @@ void JIT::emit_op_enter_with_activation(Instruction* currentInstruction) void JIT::emit_op_create_arguments(Instruction*) { - Jump argsNotCell = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::CellTag)); - Jump argsNotNull = branchTestPtr(NonZero, payloadFor(RegisterFile::ArgumentsRegister, callFrameRegister)); + Jump argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag)); // If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation. if (m_codeBlock->m_numParameters == 1) @@ -1390,8 +1460,7 @@ void JIT::emit_op_create_arguments(Instruction*) else JITStubCall(this, cti_op_create_arguments).call(); - argsNotCell.link(this); - argsNotNull.link(this); + argsCreated.link(this); } void JIT::emit_op_init_arguments(Instruction*) @@ -1723,7 +1792,6 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // Setup arg4: This is a plain hack move(stackPointerRegister, ARMRegisters::S0); - move(ctiReturnRegister, ARMRegisters::lr); call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data))); addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); @@ -1754,7 +1822,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); restoreReturnAddressBeforeReturn(regT2); @@ -1830,8 +1898,8 @@ void JIT::emit_op_end(Instruction* currentInstruction) void JIT::emit_op_jmp(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); - RECORD_JUMP_TARGET(target + 1); + addJump(jump(), target); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_loop(Instruction* currentInstruction) @@ -1839,7 +1907,7 @@ void JIT::emit_op_loop(Instruction* currentInstruction) emitTimeoutCheck(); unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop_if_less(Instruction* currentInstruction) @@ -1857,7 +1925,7 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThan, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); @@ -1866,12 +1934,12 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThan, regT0, regT1), target + 3); + addJump(branch32(LessThan, regT0, regT1), target); } } @@ -1890,12 +1958,12 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3); + addJump(branch32(LessThanOrEqual, regT0, regT1), target); } } @@ -1906,30 +1974,26 @@ void JIT::emit_op_new_object(Instruction* currentInstruction) void JIT::emit_op_instanceof(Instruction* currentInstruction) { + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + // Load the operands (baseVal, proto, and value respectively) into registers. // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); - emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); - emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); + emitGetVirtualRegister(value, regT2); + emitGetVirtualRegister(baseVal, regT0); + emitGetVirtualRegister(proto, regT1); // Check that baseVal & proto are cells. - emitJumpSlowCaseIfNotJSCell(regT0); - emitJumpSlowCaseIfNotJSCell(regT1); + emitJumpSlowCaseIfNotJSCell(regT2, value); + emitJumpSlowCaseIfNotJSCell(regT0, baseVal); + emitJumpSlowCaseIfNotJSCell(regT1, proto); - // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + // Check that baseVal 'ImplementsDefaultHasInstance'. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance))); - // If value is not an Object, return false. - Jump valueIsImmediate = emitJumpIfNotJSCell(regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); - - // Check proto is object. - loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); - // Optimistically load the result true, and start looping. // Initially, regT1 still contains proto and regT2 still contains value. // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain. @@ -1941,16 +2005,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); Jump isInstance = branchPtr(Equal, regT2, regT1); - branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop); + emitJumpIfJSCell(regT2).linkTo(loop, this); // We get here either by dropping out of the loop, or if value was not an Object. Result is false. - valueIsImmediate.link(this); - valueIsNotObject.link(this); move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0); // isInstance jumps right down to here, to skip setting the result to false (it has already set true). isInstance.link(this); - emitPutVirtualRegister(currentInstruction[1].u.operand); + emitPutVirtualRegister(dst); } void JIT::emit_op_new_func(Instruction* currentInstruction) @@ -2127,9 +2189,9 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); @@ -2196,14 +2258,14 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) unsigned target = currentInstruction[2].u.operand; emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target); Jump isNonZero = emitJumpIfImmediateInteger(regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true))))); isNonZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jeq_null(Instruction* currentInstruction) { @@ -2215,16 +2277,16 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jneq_null(Instruction* currentInstruction) { @@ -2236,16 +2298,16 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) @@ -2255,9 +2317,9 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) unsigned target = currentInstruction[3].u.operand; emitGetVirtualRegister(src, regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target + 3); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target); - RECORD_JUMP_TARGET(target + 3); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jsr(Instruction* currentInstruction) @@ -2265,10 +2327,10 @@ void JIT::emit_op_jsr(Instruction* currentInstruction) int retAddrDst = currentInstruction[1].u.operand; int target = currentInstruction[2].u.operand; DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst)); - addJump(jump(), target + 2); + addJump(jump(), target); m_jsrSites.append(JSRInfo(storeLocation, label())); killLastResultRegister(); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_sret(Instruction* currentInstruction) @@ -2320,13 +2382,13 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_neq(Instruction* currentInstruction) @@ -2377,15 +2439,116 @@ void JIT::emit_op_throw(Instruction* currentInstruction) #endif } +void JIT::emit_op_get_pnames(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int breakTarget = currentInstruction[5].u.operand; + + JumpList isNotObject; + + emitGetVirtualRegister(base, regT0); + if (!m_codeBlock->isKnownNotImmediate(base)) + isNotObject.append(emitJumpIfNotJSCell(regT0)); + if (base != m_codeBlock->thisRegister()) { + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + } + + // We could inline the case where you have a valid cache, but + // this call doesn't seem to be hot. + Label isObject(this); + JITStubCall getPnamesStubCall(this, cti_op_get_pnames); + getPnamesStubCall.addArgument(regT0); + getPnamesStubCall.call(dst); + load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3); + store32(Imm32(0), addressFor(i)); + store32(regT3, addressFor(size)); + Jump end = jump(); + + isNotObject.link(this); + move(regT0, regT1); + and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT1); + addJump(branch32(Equal, regT1, Imm32(JSImmediate::FullTagTypeNull)), breakTarget); + + JITStubCall toObjectStubCall(this, cti_to_object); + toObjectStubCall.addArgument(regT0); + toObjectStubCall.call(base); + jump().linkTo(isObject, this); + + end.link(this); +} + void JIT::emit_op_next_pname(Instruction* currentInstruction) { - JITStubCall stubCall(this, cti_op_next_pname); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int it = currentInstruction[5].u.operand; + int target = currentInstruction[6].u.operand; + + JumpList callHasProperty; + + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); + + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + +#if USE(JSVALUE64) + loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2); +#else + loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2); +#endif + + emitPutVirtualRegister(dst, regT2); + + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + emitGetVirtualRegister(base, regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); + + // Test base's prototype chain + loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3); + loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3); + addJump(branchTestPtr(Zero, Address(regT3)), target); + + Label checkPrototype(this); + loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); + callHasProperty.append(emitJumpIfNotJSCell(regT2)); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3))); + addPtr(Imm32(sizeof(Structure*)), regT3); + branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this); + + // Continue loop. + addJump(jump(), target); + + // Slow case: Ask the object if i is valid. + callHasProperty.link(this); + emitGetVirtualRegister(dst, regT1); + JITStubCall stubCall(this, cti_has_property); + stubCall.addArgument(regT0); + stubCall.addArgument(regT1); stubCall.call(); - Jump endOfIter = branchTestPtr(Zero, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); - addJump(jump(), currentInstruction[3].u.operand + 3); - endOfIter.link(this); + + // Test for valid key. + addJump(branchTest32(NonZero, regT0), target); + jump().linkTo(begin, this); + + // End of loop. + end.link(this); } void JIT::emit_op_push_scope(Instruction* currentInstruction) @@ -2469,8 +2632,8 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); - addJump(jump(), currentInstruction[2].u.operand + 2); - RECORD_JUMP_TARGET(currentInstruction[2].u.operand + 2); + addJump(jump(), currentInstruction[2].u.operand); + RECORD_JUMP_TARGET(currentInstruction[2].u.operand); } void JIT::emit_op_switch_imm(Instruction* currentInstruction) @@ -2696,32 +2859,20 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowC void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. - Label beginGetByValSlow(this); + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base array check + linkSlowCase(iter); // vector length check + linkSlowCase(iter); // empty value - notImm.link(this); JITStubCall stubCall(this, cti_op_get_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.call(currentInstruction[1].u.operand); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - // This is slow void JIT::emitSlow_that handles accesses to arrays above the fast cut-off. - // First, check if this is an access to the vector - linkSlowCase(iter); - branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), beginGetByValSlow); - - // okay, missed the fast region, but it is still in the vector. Get the value. - loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT2); - // Check whether the value loaded is zero; if so we need to return undefined. - branchTestPtr(Zero, regT2, beginGetByValSlow); - move(regT2, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand, regT0); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2735,14 +2886,14 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2750,7 +2901,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } } @@ -2764,7 +2915,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(regT0); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2772,36 +2923,26 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - // Normal slow cases - either is not an immediate imm, or is an array. - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; - notImm.link(this); { - JITStubCall stubCall(this, cti_op_put_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val)); - } + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base not array check + linkSlowCase(iter); // in vector check - // slow cases for immediate int accesses to arrays - linkSlowCase(iter); - linkSlowCase(iter); { - JITStubCall stubCall(this, cti_op_put_by_val_array); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - } + JITStubCall stubPutByValCall(this, cti_op_put_by_val); + stubPutByValCall.addArgument(regT0); + stubPutByValCall.addArgument(property, regT2); + stubPutByValCall.addArgument(value, regT2); + stubPutByValCall.call(); } void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2810,7 +2951,7 @@ void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowC JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2828,7 +2969,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted! + emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted! } void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2845,7 +2986,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2911,16 +3052,20 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + + linkSlowCaseIfNotJSCell(iter, value); + linkSlowCaseIfNotJSCell(iter, baseVal); + linkSlowCaseIfNotJSCell(iter, proto); linkSlowCase(iter); JITStubCall stubCall(this, cti_op_instanceof); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.addArgument(currentInstruction[4].u.operand, regT2); - stubCall.call(currentInstruction[1].u.operand); + stubCall.addArgument(value, regT2); + stubCall.addArgument(baseVal, regT2); + stubCall.addArgument(proto, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp index 08b3096287..bf367a6077 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -33,6 +33,7 @@ #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" +#include "JSPropertyNameIterator.h" #include "Interpreter.h" #include "LinkBuffer.h" #include "RepatchBuffer.h" @@ -273,11 +274,14 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); + + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag))); + emitStore(dst, regT1, regT0); map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); } @@ -288,35 +292,16 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas unsigned base = currentInstruction[2].u.operand; unsigned property = currentInstruction[3].u.operand; - // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. - Label callGetByValJITStub(this); - linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base array check + linkSlowCase(iter); // vector length check + linkSlowCase(iter); // empty value JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(base); stubCall.addArgument(property); stubCall.call(dst); - - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - linkSlowCase(iter); // array fast cut-off check - - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), callGetByValJITStub); - - // Missed the fast region, but it is still in the vector. - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload - - // FIXME: Maybe we can optimize this comparison to JSValue(). - Jump skip = branch32(NotEqual, regT0, Imm32(0)); - branch32(Equal, regT1, Imm32(JSValue::CellTag), callGetByValJITStub); - - skip.link(this); - emitStore(dst, regT1, regT0); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) @@ -330,24 +315,27 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - Jump inFastVector = branch32(Below, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); - - // Check if the access is within the vector. - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); - - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - Jump skip = branch32(NotEqual, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::CellTag)); - addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), Imm32(0))); - skip.link(this); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); - inFastVector.link(this); + Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag)); + Label storeResult(this); emitLoad(value, regT1, regT0); store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); // payload store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4)); // tag + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + add32(Imm32(1), regT2, regT0); + store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -359,24 +347,13 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check + linkSlowCase(iter); // in vector check JITStubCall stubPutByValCall(this, cti_op_put_by_val); stubPutByValCall.addArgument(base); stubPutByValCall.addArgument(property); stubPutByValCall.addArgument(value); stubPutByValCall.call(); - - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - // Slow cases for immediate int accesses to arrays. - linkSlowCase(iter); // in vector check - linkSlowCase(iter); // written to slot check - - JITStubCall stubCall(this, cti_op_put_by_val_array); - stubCall.addArgument(regT1, regT0); - stubCall.addArgument(regT2); - stubCall.addArgument(value); - stubCall.call(); } void JIT::emit_op_get_by_id(Instruction* currentInstruction) @@ -545,22 +522,26 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res load32(Address(temp, offset + 4), resultTag); } +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure))); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack. JumpList failureCases; failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); - - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(oldStructure))); + failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); + testPrototype(oldStructure, failureCases); // Verify that nothing in the prototype chain has a setter for this property. - for (RefPtr<Structure>* it = chain->head(); *it; ++it) { - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(it->get()))); - } + for (RefPtr<Structure>* it = chain->head(); *it; ++it) + testPrototype(it->get(), failureCases); // Reallocate property storage if needed. Call callTarget; @@ -954,16 +935,83 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) +void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset) +{ + ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSValue) == 8); + + Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + Jump finishedLoad = jump(); + notUsingInlineStorage.link(this); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + finishedLoad.link(this); +} + +void JIT::emit_op_get_by_pname(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitLoad2(property, regT1, regT0, base, regT3, regT2); + emitJumpSlowCaseIfNotJSCell(property, regT1); + addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected))); + // Property registers are now available as the property is known + emitJumpSlowCaseIfNotJSCell(base, regT3); + emitLoadPayload(iter, regT1); + + // Test base's structure + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); + addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + load32(addressFor(i), regT3); + sub32(Imm32(1), regT3); + addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); + compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3); + + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCaseIfNotJSCell(iter, property); + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base); + stubCall.addArgument(property); + stubCall.call(dst); +} + #else // USE(JSVALUE32_64) void JIT::emit_op_get_by_val(Instruction* currentInstruction) { - emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1); + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); #if USE(JSVALUE64) // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. - // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if - // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation + // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if + // number was signed since m_vectorLength is always less than intmax (since the total allocation // size is always less than 4Gb). As such zero extending wil have been correct (and extending the value // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign // extending since it makes it easier to re-tag the value in the slow case. @@ -971,21 +1019,67 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) #else emitFastArithImmToInt(regT1); #endif - emitJumpSlowCaseIfNotJSCell(regT0); + emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // Get the value from the vector loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); + addSlowCase(branchTestPtr(Zero, regT0)); + + emitPutVirtualRegister(dst); +} + +void JIT::emit_op_get_by_pname(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitGetVirtualRegister(property, regT0); + addSlowCase(branchPtr(NotEqual, regT0, addressFor(expected))); + emitGetVirtualRegisters(base, regT0, iter, regT1); + emitJumpSlowCaseIfNotJSCell(regT0, base); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + load32(addressFor(i), regT3); + sub32(Imm32(1), regT3); + addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); + compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1); + + emitPutVirtualRegister(dst, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) { - emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); #if USE(JSVALUE64) // See comment in op_get_by_val. @@ -993,23 +1087,29 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) #else emitFastArithImmToInt(regT1); #endif - emitJumpSlowCaseIfNotJSCell(regT0); + emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - Jump inFastVector = branch32(Below, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); - // No; oh well, check if the access if within the vector - if so, we may still be okay. - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); + Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - // All good - put the value into the array. - inFastVector.link(this); - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); + Label storeResult(this); + emitGetVirtualRegister(value, regT0); storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + move(regT1, regT0); + add32(Imm32(1), regT0); + store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emit_op_put_by_index(Instruction* currentInstruction) @@ -1138,9 +1238,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) Jump match = jump(); - ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); - ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct); - ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); // Link the failure cases here. notCell.link(this); @@ -1207,22 +1307,22 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert DataLabelPtr structureToCompare; Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); addSlowCase(structureCheck); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure); - ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase) Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad); DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset); Label putResult(this); END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); - ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); } void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1257,7 +1357,7 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); - ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); + ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall); // Track the location of the call; this will be used to recover patch information. m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; @@ -1288,19 +1388,19 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over. DataLabelPtr structureToCompare; addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)))); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure); // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used. Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad); DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset)); END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetPutByIdPropertyMapOffset); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1357,35 +1457,41 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res } } +void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) +{ + ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); + + Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); + loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); + Jump finishedLoad = jump(); + notUsingInlineStorage.link(this); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); + loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); + finishedLoad.link(this); +} + +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + move(ImmPtr(&asCell(structure->m_prototype)->m_structure), regT2); + move(ImmPtr(asCell(structure->m_prototype)->m_structure), regT3); + failureCases.append(branchPtr(NotEqual, Address(regT2), regT3)); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { JumpList failureCases; // Check eax is an object of the right Structure. failureCases.append(emitJumpIfNotJSCell(regT0)); failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); - JumpList successCases; - - // ecx = baseObject - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - // proto(ecx) = baseObject->structure()->prototype() - failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType))); + testPrototype(oldStructure, failureCases); - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - // ecx = baseObject->m_structure - for (RefPtr<Structure>* it = chain->head(); *it; ++it) { - // null check the prototype - successCases.append(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNull())))); - - // Check the structure id - failureCases.append(branchPtr(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(it->get()))); - - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType))); - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - } - - successCases.link(this); + for (RefPtr<Structure>* it = chain->head(); *it; ++it) + testPrototype(it->get(), failureCases); Call callTarget; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h index cb5354b9b8..c5ed9e3a48 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h @@ -26,7 +26,7 @@ #ifndef JITStubCall_h #define JITStubCall_h -#include <wtf/Platform.h> +#include "MacroAssemblerCodeRef.h" #if ENABLE(JIT) @@ -36,7 +36,7 @@ namespace JSC { public: JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Cell) , m_stackIndex(stackIndexStart) { @@ -44,7 +44,7 @@ namespace JSC { JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Cell) , m_stackIndex(stackIndexStart) { @@ -52,7 +52,7 @@ namespace JSC { JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(VoidPtr) , m_stackIndex(stackIndexStart) { @@ -60,7 +60,7 @@ namespace JSC { JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Int) , m_stackIndex(stackIndexStart) { @@ -68,7 +68,7 @@ namespace JSC { JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Int) , m_stackIndex(stackIndexStart) { @@ -76,7 +76,7 @@ namespace JSC { JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Void) , m_stackIndex(stackIndexStart) { @@ -85,7 +85,7 @@ namespace JSC { #if USE(JSVALUE32_64) JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Value) , m_stackIndex(stackIndexStart) { @@ -171,7 +171,7 @@ namespace JSC { m_jit->restoreArgumentReference(); JIT::Call call = m_jit->call(); - m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub)); + m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub.value())); #if ENABLE(OPCODE_SAMPLING) if (m_jit->m_bytecodeIndex != (unsigned)-1) @@ -225,7 +225,7 @@ namespace JSC { static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference(). JIT* m_jit; - void* m_stub; + FunctionPtr m_stub; enum { Void, VoidPtr, Int, Value, Cell } m_returnType; size_t m_stackIndex; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp index 065b7ea477..8385f929b3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp @@ -75,6 +75,25 @@ namespace JSC { #define THUMB_FUNC_PARAM(name) #endif +#if PLATFORM(LINUX) && PLATFORM(X86_64) +#define SYMBOL_STRING_RELOCATION(name) #name "@plt" +#else +#define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name) +#endif + +#if PLATFORM(DARWIN) + // Mach-O platform +#define HIDE_SYMBOL(name) ".private_extern _" #name +#elif PLATFORM(AIX) + // IBM's own file format +#define HIDE_SYMBOL(name) ".lglobl " #name +#elif PLATFORM(LINUX) || PLATFORM(FREEBSD) || PLATFORM(OPENBSD) || PLATFORM(SOLARIS) || (PLATFORM(HPUX) && PLATFORM(IA64)) || PLATFORM(SYMBIAN) || PLATFORM(NETBSD) + // ELF platform +#define HIDE_SYMBOL(name) ".hidden " #name +#else +#define HIDE_SYMBOL(name) +#endif + #if USE(JSVALUE32_64) #if COMPILER(GCC) && PLATFORM(X86) @@ -87,7 +106,9 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline); asm volatile ( +".text\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "pushl %ebp" "\n" "movl %esp, %ebp" "\n" @@ -108,11 +129,12 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" #if !USE(JIT_STUB_ARGUMENT_VA_LIST) "movl %esp, %ecx" "\n" #endif - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addl $0x3c, %esp" "\n" "popl %ebx" "\n" "popl %edi" "\n" @@ -123,6 +145,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "addl $0x3c, %esp" "\n" "popl %ebx" "\n" @@ -147,6 +170,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_ asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "pushq %rbp" "\n" "movq %rsp, %rbp" "\n" @@ -173,9 +197,10 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addq $0x48, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" @@ -188,6 +213,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "addq $0x48, %rsp" "\n" "popq %rbx" "\n" @@ -209,6 +235,7 @@ asm volatile ( ".text" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" @@ -235,11 +262,12 @@ asm volatile ( ".text" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" - "bl " SYMBOL_STRING(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" @@ -340,7 +368,9 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x30, JITStackFrame_code_ COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_stub_argument_space_matches_ctiTrampoline); asm volatile ( +".text\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "pushl %ebp" "\n" "movl %esp, %ebp" "\n" @@ -361,11 +391,12 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" #if !USE(JIT_STUB_ARGUMENT_VA_LIST) "movl %esp, %ecx" "\n" #endif - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addl $0x1c, %esp" "\n" "popl %ebx" "\n" "popl %edi" "\n" @@ -376,6 +407,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "addl $0x1c, %esp" "\n" "popl %ebx" "\n" @@ -398,7 +430,9 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x48, JITStackFrame_code_ COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x78, JITStackFrame_stub_argument_space_matches_ctiTrampoline); asm volatile ( +".text\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "pushq %rbp" "\n" "movq %rsp, %rbp" "\n" @@ -432,9 +466,10 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addq $0x78, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" @@ -447,6 +482,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "addq $0x78, %rsp" "\n" "popq %rbx" "\n" @@ -468,6 +504,7 @@ asm volatile ( ".text" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" @@ -494,11 +531,12 @@ asm volatile ( ".text" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" - "bl " SYMBOL_STRING(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" @@ -511,6 +549,7 @@ asm volatile ( ".text" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" @@ -525,41 +564,35 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL) asm volatile ( +".text\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "stmdb sp!, {r1-r3}" "\n" "stmdb sp!, {r4-r8, lr}" "\n" - "mov r6, pc" "\n" - "add r6, r6, #40" "\n" - "sub sp, sp, #32" "\n" - "ldr r4, [sp, #60]" "\n" + "sub sp, sp, #36" "\n" + "mov r4, r2" "\n" "mov r5, #512" "\n" - // r0 contains the code - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" + "mov lr, pc" "\n" "mov pc, r0" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" - - // the return instruction - "ldr pc, [sp], #4" "\n" ); asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" - "mov lr, r6" "\n" - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" - "b " SYMBOL_STRING(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" // Both has the same return sequence ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" @@ -694,11 +727,15 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { - StructureChain* prototypeChain = structure->prototypeChain(callFrame); - if (!prototypeChain->isCacheable() || structure->isDictionary()) { + if (structure->isDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } + + // put_by_id_transition checks the prototype chain for setters. + normalizePrototypeChain(callFrame, baseCell); + + StructureChain* prototypeChain = structure->prototypeChain(callFrame); stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain); JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress); return; @@ -758,6 +795,11 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co return; } + if (structure->isDictionary()) { + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); + return; + } + if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { ASSERT(slot.slotBase().isObject()); @@ -774,17 +816,13 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co return; } - size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); if (!count) { stubInfo->accessType = access_get_by_id_generic; return; } StructureChain* prototypeChain = structure->prototypeChain(callFrame); - if (!prototypeChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); - return; - } stubInfo->initGetByIdChain(structure, prototypeChain); JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress); } @@ -892,6 +930,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ".text" "\n" \ ".align 2" "\n" \ ".globl " SYMBOL_STRING(cti_##op) "\n" \ + HIDE_SYMBOL(cti_##op) "\n" \ ".thumb" "\n" \ ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \ SYMBOL_STRING(cti_##op) ":" "\n" \ @@ -902,6 +941,22 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \ +#elif PLATFORM(ARM_TRADITIONAL) && COMPILER(GCC) + +#define DEFINE_STUB_FUNCTION(rtype, op) \ + extern "C" { \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \ + }; \ + asm volatile ( \ + ".globl " SYMBOL_STRING(cti_##op) "\n" \ + SYMBOL_STRING(cti_##op) ":" "\n" \ + "str lr, [sp, #32]" "\n" \ + "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ + "ldr lr, [sp, #32]" "\n" \ + "mov pc, lr" "\n" \ + ); \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) + #else #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif @@ -1326,15 +1381,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); - } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) { - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); - return JSValue::encode(result); - } - + } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase())) { int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + + StructureChain* protoChain = structure->prototypeChain(callFrame); JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) @@ -1412,7 +1463,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof) // ECMA-262 15.3.5.3: // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function). - TypeInfo typeInfo(UnspecifiedType, 0); + TypeInfo typeInfo(UnspecifiedType); if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) { CallFrame* callFrame = stackFrame.callFrame; CodeBlock* codeBlock = callFrame->codeBlock(); @@ -1942,28 +1993,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) CHECK_FOR_EXCEPTION_AT_END(); } -DEFINE_STUB_FUNCTION(void, op_put_by_val_array) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - JSValue baseValue = stackFrame.args[0].jsValue(); - int i = stackFrame.args[1].int32(); - JSValue value = stackFrame.args[2].jsValue(); - - ASSERT(isJSArray(stackFrame.globalData, baseValue)); - - if (LIKELY(i >= 0)) - asArray(baseValue)->JSArray::put(callFrame, i, value); - else { - Identifier property(callFrame, UString::from(i)); - PutPropertySlot slot; - baseValue.put(callFrame, property, value, slot); - } - - CHECK_FOR_EXCEPTION_AT_END(); -} - DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2672,7 +2701,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw) if (!handler) { *stackFrame.exception = exceptionValue; - STUB_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiOpThrowNotCaught)); + STUB_SET_RETURN_ADDRESS(FunctionPtr(ctiOpThrowNotCaught).value()); return JSValue::encode(jsNull()); } @@ -2687,18 +2716,22 @@ DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames) { STUB_INIT_STACK_FRAME(stackFrame); - return JSPropertyNameIterator::create(stackFrame.callFrame, stackFrame.args[0].jsValue()); + CallFrame* callFrame = stackFrame.callFrame; + JSObject* o = stackFrame.args[0].jsObject(); + Structure* structure = o->structure(); + JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); + if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) + jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); + return jsPropertyNameIterator; } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_next_pname) +DEFINE_STUB_FUNCTION(int, has_property) { STUB_INIT_STACK_FRAME(stackFrame); - JSPropertyNameIterator* it = stackFrame.args[0].propertyNameIterator(); - JSValue temp = it->next(stackFrame.callFrame); - if (!temp) - it->invalidate(); - return JSValue::encode(temp); + JSObject* base = stackFrame.args[0].jsObject(); + JSString* property = stackFrame.args[1].jsString(); + return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value())); } DEFINE_STUB_FUNCTION(JSObject*, op_push_scope) @@ -3039,6 +3072,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw) return JSValue::encode(exceptionValue); } +DEFINE_STUB_FUNCTION(EncodedJSValue, to_object) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + CallFrame* callFrame = stackFrame.callFrame; + return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame)); +} + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h index 46973eed03..69776cb337 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h @@ -63,6 +63,7 @@ namespace JSC { int32_t asInt32; JSValue jsValue() { return JSValue::decode(asEncodedJSValue); } + JSObject* jsObject() { return static_cast<JSObject*>(asPointer); } Identifier& identifier() { return *static_cast<Identifier*>(asPointer); } int32_t int32() { return asInt32; } CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); } @@ -162,6 +163,8 @@ namespace JSC { JITStubArg padding; // Unused JITStubArg args[7]; + ReturnAddressPtr thunkReturnAddress; + void* preservedR4; void* preservedR5; void* preservedR6; @@ -172,11 +175,13 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; JSValue* exception; + + // These arguments passed on the stack. Profiler** enabledProfilerReference; JSGlobalData* globalData; // When JIT code makes a call, it pushes its return address just below the rest of the stack. - ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } + ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; #else #error "JITStackFrame not defined for this platform." @@ -285,7 +290,6 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION); @@ -307,6 +311,7 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION); @@ -332,6 +337,7 @@ extern "C" { int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION); int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION); int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION); + int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION); @@ -345,7 +351,6 @@ extern "C" { void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_val_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION); diff --git a/src/3rdparty/webkit/JavaScriptCore/jsc.cpp b/src/3rdparty/webkit/JavaScriptCore/jsc.cpp index 9399b1a9e3..b6bc0aad3f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jsc.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jsc.cpp @@ -29,6 +29,7 @@ #include "JSArray.h" #include "JSFunction.h" #include "JSLock.h" +#include "JSString.h" #include "PrototypeFunction.h" #include "SamplingTool.h" #include <math.h> diff --git a/src/3rdparty/webkit/JavaScriptCore/jsc.pro b/src/3rdparty/webkit/JavaScriptCore/jsc.pro deleted file mode 100644 index ba880ffbda..0000000000 --- a/src/3rdparty/webkit/JavaScriptCore/jsc.pro +++ /dev/null @@ -1,31 +0,0 @@ -TEMPLATE = app -TARGET = jsc -DESTDIR = . -SOURCES = jsc.cpp -QT -= gui -CONFIG -= app_bundle -CONFIG += building-libs -win32-*: CONFIG += console -win32-msvc*: CONFIG += exceptions_off stl_off - -include($$PWD/../WebKit.pri) - -CONFIG += link_pkgconfig - -QMAKE_RPATHDIR += $$OUTPUT_DIR/lib - -isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/.. -CONFIG(debug, debug|release) { - OBJECTS_DIR = obj/debug -} else { # Release - OBJECTS_DIR = obj/release -} -OBJECTS_DIR_WTR = $$OBJECTS_DIR$${QMAKE_DIR_SEP} -include($$PWD/JavaScriptCore.pri) - -lessThan(QT_MINOR_VERSION, 4) { - DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE="" -} - -*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 -*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y index 85fd16321c..6d953dfed1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y @@ -27,6 +27,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Lexer.h" #include "NodeConstructors.h" #include "NodeInfo.h" #include <stdlib.h> @@ -48,7 +49,6 @@ #define YYERROR_VERBOSE #endif -int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp index 785b219fe7..df3083834f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp @@ -46,12 +46,6 @@ using namespace JSC; #include "Lookup.h" #include "Lexer.lut.h" -// A bridge for yacc from the C world to the C++ world. -int jscyylex(void* lvalp, void* llocp, void* globalData) -{ - return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); -} - namespace JSC { static const UChar byteOrderMark = 0xFEFF; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h index 174e05a8c4..c76696cf3b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h @@ -136,6 +136,12 @@ namespace JSC { return (convertHex(c1, c2) << 8) | convertHex(c3, c4); } + // A bridge for yacc from the C world to the C++ world. + inline int jscyylex(void* lvalp, void* llocp, void* globalData) + { + return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); + } + } // namespace JSC #endif // Lexer_h diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp index 3bd318a04c..45009dce44 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp @@ -1468,20 +1468,24 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds if (!m_lexpr->isLocation()) return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference."); - RefPtr<Label> continueTarget = generator.newLabel(); - generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_init) generator.emitNode(generator.ignoredResult(), m_init); - RegisterID* forInBase = generator.emitNode(m_expr); - RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase); + + RefPtr<RegisterID> base = generator.newTemporary(); + generator.emitNode(base.get(), m_expr); + RefPtr<RegisterID> i = generator.newTemporary(); + RefPtr<RegisterID> size = generator.newTemporary(); + RefPtr<RegisterID> expectedSubscript; + RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); generator.emitJump(scope->continueTarget()); RefPtr<Label> loopStart = generator.newLabel(); generator.emitLabel(loopStart.get()); RegisterID* propertyName; + bool optimizedForinAccess = false; if (m_lexpr->isResolveNode()) { const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); propertyName = generator.registerFor(ident); @@ -1492,6 +1496,10 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitExpressionInfo(divot(), startOffset(), endOffset()); generator.emitPutById(base, ident, propertyName); + } else { + expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); + generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); + optimizedForinAccess = true; } } else if (m_lexpr->isDotAccessorNode()) { DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); @@ -1516,8 +1524,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitNode(dst, m_statement); + if (optimizedForinAccess) + generator.popOptimisedForIn(); + generator.emitLabel(scope->continueTarget()); - generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get()); + generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); generator.emitLabel(scope->breakTarget()); return dst; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h index 2fd4fc1410..eef8e93939 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h @@ -34,7 +34,7 @@ namespace JSC { class ParserArenaDeletable; class ParserArenaRefCounted; - class IdentifierArena { + class IdentifierArena : public FastAllocBase { public: ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length); const Identifier& makeNumericIdentifier(JSGlobalData*, double number); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h index 5be84a27a3..9b674a2fad 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h @@ -85,9 +85,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + private: void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp index 0237fd4d53..fb44494051 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -50,7 +50,7 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, NonNullPassRefPtr<Structure> putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum); } -static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) +static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) { // a single numeric argument denotes the array size (!) if (args.size() == 1 && args.at(0).isNumber()) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp index 86e3f1b09c..7a894478c6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -149,10 +149,11 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.inherits(&JSArray::info)) + bool isRealArray = isJSArray(&exec->globalData(), thisValue); + if (!isRealArray && !thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); - JSObject* thisObj = asArray(thisValue); - + JSArray* thisObj = asArray(thisValue); + HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) { if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth) @@ -163,34 +164,48 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue if (alreadyVisited) return jsEmptyString(exec); // return an empty string, avoiding infinite recursion. - Vector<UChar, 256> strBuffer; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned totalSize = length ? length - 1 : 0; + Vector<RefPtr<UString::Rep>, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { - if (k >= 1) - strBuffer.append(','); - if (!strBuffer.data()) { - JSObject* error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - break; - } - - JSValue element = thisObj->get(exec, k); + JSValue element; + if (isRealArray && thisObj->canGetIndex(k)) + element = thisObj->getIndex(k); + else + element = thisObj->get(exec, k); + if (element.isUndefinedOrNull()) continue; - + UString str = element.toString(exec); - strBuffer.append(str.data(), str.size()); - + strBuffer[k] = str.rep(); + totalSize += str.size(); + if (!strBuffer.data()) { JSObject* error = Error::create(exec, GeneralError, "Out of memory"); exec->setException(error); } - + if (exec->hadException()) break; } arrayVisitedElements.remove(thisObj); - return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0)); + if (!totalSize) + return jsEmptyString(exec); + Vector<UChar> buffer; + buffer.reserveCapacity(totalSize); + if (!buffer.data()) + return throwError(exec, GeneralError, "Out of memory"); + + for (unsigned i = 0; i < length; i++) { + if (i) + buffer.append(','); + if (RefPtr<UString::Rep> rep = strBuffer[i]) + buffer.append(rep->data(), rep->size()); + } + ASSERT(buffer.size() == totalSize); + unsigned finalSize = buffer.size(); + return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false)); } JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h index 28f796aaad..69c2e51349 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp index 01e36c401c..8b647a09be 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp @@ -1043,16 +1043,6 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack) #endif } -void Heap::setGCProtectNeedsLocking() -{ - // Most clients do not need to call this, with the notable exception of WebCore. - // Clients that use shared heap have JSLock protection, while others are supposed - // to do explicit locking. WebCore violates this contract in Database code, - // which calls gcUnprotect from a secondary thread. - if (!m_protectedValuesMutex) - m_protectedValuesMutex.set(new Mutex); -} - void Heap::protect(JSValue k) { ASSERT(k); @@ -1061,13 +1051,7 @@ void Heap::protect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.add(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::unprotect(JSValue k) @@ -1078,28 +1062,16 @@ void Heap::unprotect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.remove(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::markProtectedObjects(MarkStack& markStack) { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) { markStack.append(it->first); markStack.drain(); } - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } template <HeapType heapType> size_t Heap::sweep() @@ -1291,9 +1263,6 @@ size_t Heap::globalObjectCount() size_t Heap::protectedGlobalObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - size_t count = 0; if (JSGlobalObject* head = m_globalData->head) { JSGlobalObject* o = head; @@ -1304,23 +1273,12 @@ size_t Heap::protectedGlobalObjectCount() } while (o != head); } - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return count; } size_t Heap::protectedObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - - size_t result = m_protectedValues.size(); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - - return result; + return m_protectedValues.size(); } static const char* typeName(JSCell* cell) @@ -1333,6 +1291,10 @@ static const char* typeName(JSCell* cell) #endif if (cell->isGetterSetter()) return "gettersetter"; + if (cell->isAPIValueWrapper()) + return "value wrapper"; + if (cell->isPropertyNameIterator()) + return "for-in iterator"; ASSERT(cell->isObject()); const ClassInfo* info = cell->classInfo(); return info ? info->className : "Object"; @@ -1342,16 +1304,10 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts() { HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) counts->add(typeName(it->first)); - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return counts; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h index 0ecff190e4..9ca9d18f01 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h @@ -71,14 +71,6 @@ namespace JSC { void destroy(); -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - // We can inline these functions because everything is compiled as - // one file, so the heapAllocate template definitions are available. - // However, allocateNumber is used via jsNumberCell outside JavaScriptCore. - // Thus allocateNumber needs to provide a non-inline version too. - void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); } - void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); } -#endif void* allocateNumber(size_t); void* allocate(size_t); @@ -96,7 +88,6 @@ namespace JSC { }; Statistics statistics() const; - void setGCProtectNeedsLocking(); void protect(JSValue); void unprotect(JSValue); @@ -151,7 +142,6 @@ namespace JSC { CollectorHeap primaryHeap; CollectorHeap numberHeap; - OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking(). ProtectCountSet m_protectedValues; HashSet<MarkedArgumentBuffer*>* m_markListSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp index f9b7d84f5b..9908fef80c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp @@ -112,9 +112,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args) } } - DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure()); - result->setInternalValue(jsNumber(exec, timeClip(value))); - return result; + return new (exec) DateInstance(exec, value); } static JSObject* constructWithDateConstructor(ExecState* exec, JSObject*, const ArgList& args) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp index 6b479ae43a..d4c9ef7408 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp @@ -22,6 +22,8 @@ #include "config.h" #include "DateInstance.h" +#include "JSGlobalObject.h" + #include <math.h> #include <wtf/DateMath.h> #include <wtf/MathExtras.h> @@ -30,88 +32,43 @@ using namespace WTF; namespace JSC { -struct DateInstance::Cache { - double m_gregorianDateTimeCachedForMS; - GregorianDateTime m_cachedGregorianDateTime; - double m_gregorianDateTimeUTCCachedForMS; - GregorianDateTime m_cachedGregorianDateTimeUTC; -}; - const ClassInfo DateInstance::info = {"Date", 0, 0, 0}; -DateInstance::DateInstance(NonNullPassRefPtr<Structure> structure) +DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure) : JSWrapperObject(structure) - , m_cache(0) { + setInternalValue(jsNaN(exec)); } -DateInstance::~DateInstance() +DateInstance::DateInstance(ExecState* exec, double time) + : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) { - delete m_cache; + setInternalValue(jsNumber(exec, timeClip(time))); } -void DateInstance::msToGregorianDateTime(double milli, bool outputIsUTC, GregorianDateTime& t) const +bool DateInstance::getGregorianDateTime(ExecState* exec, bool outputIsUTC, GregorianDateTime& t) const { - if (!m_cache) { - m_cache = new Cache; - m_cache->m_gregorianDateTimeCachedForMS = NaN; - m_cache->m_gregorianDateTimeUTCCachedForMS = NaN; - } + double milli = internalNumber(); + if (isnan(milli)) + return false; + + if (!m_data) + m_data = exec->globalData().dateInstanceCache.add(milli); if (outputIsUTC) { - if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) { - WTF::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC); - m_cache->m_gregorianDateTimeUTCCachedForMS = milli; + if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) { + WTF::msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC); + m_data->m_gregorianDateTimeUTCCachedForMS = milli; } - t.copyFrom(m_cache->m_cachedGregorianDateTimeUTC); + t.copyFrom(m_data->m_cachedGregorianDateTimeUTC); } else { - if (m_cache->m_gregorianDateTimeCachedForMS != milli) { - WTF::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime); - m_cache->m_gregorianDateTimeCachedForMS = milli; + if (m_data->m_gregorianDateTimeCachedForMS != milli) { + WTF::msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime); + m_data->m_gregorianDateTimeCachedForMS = milli; } - t.copyFrom(m_cache->m_cachedGregorianDateTime); + t.copyFrom(m_data->m_cachedGregorianDateTime); } -} -bool DateInstance::getTime(GregorianDateTime& t, int& offset) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return false; - - msToGregorianDateTime(milli, false, t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(GregorianDateTime& t) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return false; - - msToGregorianDateTime(milli, true, t); - return true; -} - -bool DateInstance::getTime(double& milli, int& offset) const -{ - milli = internalNumber(); - if (isnan(milli)) - return false; - - GregorianDateTime t; - msToGregorianDateTime(milli, false, t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(double& milli) const -{ - milli = internalNumber(); - if (isnan(milli)) - return false; - return true; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h index c8edc2faaa..38b321c699 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h @@ -31,27 +31,27 @@ namespace JSC { class DateInstance : public JSWrapperObject { public: - explicit DateInstance(NonNullPassRefPtr<Structure>); - virtual ~DateInstance(); + DateInstance(ExecState*, double); + explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>); double internalNumber() const { return internalValue().uncheckedGetNumber(); } - bool getTime(WTF::GregorianDateTime&, int& offset) const; - bool getUTCTime(WTF::GregorianDateTime&) const; - bool getTime(double& milliseconds, int& offset) const; - bool getUTCTime(double& milliseconds) const; + static JS_EXPORTDATA const ClassInfo info; - static const ClassInfo info; + bool getGregorianDateTime(ExecState*, bool outputIsUTC, WTF::GregorianDateTime&) const; - void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const; + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + } + + protected: + static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; private: virtual const ClassInfo* classInfo() const { return &info; } - using JSWrapperObject::internalValue; - - struct Cache; - mutable Cache* m_cache; + mutable RefPtr<DateInstanceData> m_data; }; DateInstance* asDateInstance(JSValue); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstanceCache.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstanceCache.h new file mode 100644 index 0000000000..b626c1dd28 --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstanceCache.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 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 DateInstanceCache_h +#define DateInstanceCache_h + +#include <wtf/DateMath.h> +#include <wtf/HashFunctions.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace JSC { + + extern const double NaN; + + class DateInstanceData : public RefCounted<DateInstanceData> { + public: + static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); } + + double m_gregorianDateTimeCachedForMS; + WTF::GregorianDateTime m_cachedGregorianDateTime; + double m_gregorianDateTimeUTCCachedForMS; + WTF::GregorianDateTime m_cachedGregorianDateTimeUTC; + + private: + DateInstanceData() + : m_gregorianDateTimeCachedForMS(NaN) + , m_gregorianDateTimeUTCCachedForMS(NaN) + { + } + }; + + class DateInstanceCache { + public: + DateInstanceCache() + { + for (size_t i = 0; i < cacheSize; ++i) + m_cache[i].key = NaN; + } + + DateInstanceData* add(double d) + { + CacheEntry& entry = lookup(d); + if (d == entry.key) + return entry.value.get(); + + entry.key = d; + entry.value = DateInstanceData::create(); + return entry.value.get(); + } + + private: + static const size_t cacheSize = 64; + + struct CacheEntry { + double key; + RefPtr<DateInstanceData> value; + }; + + CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } + + CacheEntry m_cache[cacheSize]; + }; + +} // namespace JSC + +#endif // DateInstanceCache_h diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp index e46ab67a32..3f3e1f915a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp @@ -251,11 +251,12 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L return jsNontrivialString(exec, timebuffer); } -static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList&) +static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format, const ArgList&) { GregorianDateTime gregorianDateTime; - const bool notUTC = false; - dateObject->msToGregorianDateTime(timeInMilliseconds, notUTC, gregorianDateTime); + const bool outputIsUTC = false; + if (!dateObject->getGregorianDateTime(exec, outputIsUTC, gregorianDateTime)) + return jsNontrivialString(exec, "Invalid Date"); return formatLocaleDate(exec, gregorianDateTime, format); } @@ -396,9 +397,8 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState // ECMA 15.9.4 DatePrototype::DatePrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure) - : DateInstance(structure) + : DateInstance(exec, structure) { - setInternalValue(jsNaN(exec)); // The constructor will be added later, after DateConstructor has been built. } @@ -420,16 +420,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -437,16 +435,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -454,19 +450,17 @@ JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (!isfinite(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds) // 6 for formatting and one for null termination = 27. We add one extra character to allow us to force null termination. char buffer[28]; - snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(milli, 1000))); + snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000))); buffer[sizeof(buffer) - 1] = 0; return jsNontrivialString(exec, buffer); } @@ -476,15 +470,13 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); return jsNontrivialString(exec, formatDate(t)); } @@ -493,16 +485,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -511,11 +501,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JS return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDateAndTime, args); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -524,11 +510,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDate, args); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -537,11 +519,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleTime, args); } JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -549,12 +527,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); - - return jsNumber(exec, milli); + return asDateInstance(thisValue)->internalValue(); } JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -562,15 +535,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, 1900 + t.year); } @@ -579,15 +550,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JS if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, 1900 + t.year); } @@ -596,16 +565,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -613,15 +580,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.month); } @@ -630,15 +595,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.month); } @@ -647,15 +610,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.monthDay); } @@ -664,15 +625,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.monthDay); } @@ -681,15 +640,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue th if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.weekDay); } @@ -698,15 +655,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.weekDay); } @@ -715,15 +670,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.hour); } @@ -732,15 +685,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.hour); } @@ -749,15 +700,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.minute); } @@ -766,15 +715,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSV if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.minute); } @@ -783,15 +730,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.second); } @@ -800,15 +745,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSV if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.second); } @@ -847,15 +790,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, -gmtoffset(t) / minutesPerHour); } @@ -890,7 +831,7 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const double ms = milli - secs * msPerSecond; GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); + thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) { JSValue result = jsNaN(exec); @@ -922,11 +863,11 @@ static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const if (numArgsToUse == 3 && isnan(milli)) // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear) // the time must be reset to +0 if it is NaN. - thisDateObj->msToGregorianDateTime(0, true, t); + WTF::msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; - thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); + thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); } if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) { @@ -1029,7 +970,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); if (args.isEmpty()) { @@ -1045,11 +986,11 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t if (isnan(milli)) // Based on ECMA 262 B.2.5 (setYear) // the time must be reset to +0 if it is NaN. - thisDateObj->msToGregorianDateTime(0, true, t); + WTF::msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; - thisDateObj->msToGregorianDateTime(milli, utc, t); + thisDateObj->getGregorianDateTime(exec, outputIsUTC, t); } bool ok = true; @@ -1061,7 +1002,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t } t.year = (year > 99 || year < 0) ? year - 1900 : year; - JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc)); + JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, outputIsUTC)); thisDateObj->setInternalValue(result); return result; } @@ -1071,15 +1012,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); // NOTE: IE returns the full year even in getYear. return jsNumber(exec, t.year); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h index caed2d4f37..f565775499 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h @@ -39,8 +39,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags; + }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp index cc18b95e97..5bead90d9f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -66,6 +66,11 @@ JSValue createStackOverflowError(ExecState* exec) return createError(exec, RangeError, "Maximum call stack size exceeded."); } +JSValue createTypeError(ExecState* exec, const char* message) +{ + return createError(exec, TypeError, message); +} + JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h index 4c5bec1079..e739d0954c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h @@ -44,6 +44,7 @@ namespace JSC { JSValue createInterruptedExecutionException(JSGlobalData*); JSValue createStackOverflowError(ExecState*); + JSValue createTypeError(ExecState*, const char* message); JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*); JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull); JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h index 0e38549745..d1d6a1d1bc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h index 73dd85473a..68e9ea3cce 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h @@ -50,7 +50,7 @@ namespace JSC { void setSetter(JSObject* setter) { m_setter = setter; } static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(GetterSetterType)); + return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren)); } private: virtual bool isGetterSetter() const; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h index b62ad3eeb5..389b1c34c2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h @@ -37,9 +37,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | PrototypeFunction::StructureFlags; + private: virtual void markChildren(MarkStack&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h index fdd5cc1c9c..de9a1d6ecb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h @@ -42,10 +42,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; + InternalFunction(NonNullPassRefPtr<Structure> structure) : JSObject(structure) { } InternalFunction(JSGlobalData*, NonNullPassRefPtr<Structure>, const Identifier&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h index 88a8493870..aca550e2f6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h index 583b988f18..ee9819106a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h @@ -66,7 +66,10 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: struct JSActivationData : public JSVariableObjectData { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp index c471dacb02..fd9e7b2e4c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -136,9 +136,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure) unsigned initialCapacity = 0; m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_vectorLength = initialCapacity; - - m_fastAccessCutoff = 0; + m_vectorLength = initialCapacity; checkConsistency(); } @@ -150,7 +148,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialLength; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = 0; m_storage->m_sparseValueMap = 0; m_storage->lazyCreationData = 0; @@ -159,8 +157,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) for (size_t i = 0; i < initialCapacity; ++i) vector[i] = JSValue(); - m_fastAccessCutoff = 0; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); @@ -173,7 +169,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialCapacity; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = initialCapacity; m_storage->m_sparseValueMap = 0; @@ -182,8 +178,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) m_storage->m_vector[i] = *it; - m_fastAccessCutoff = initialCapacity; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); @@ -207,7 +201,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot return false; } - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (valueSlot) { slot.setValueSlot(&valueSlot); @@ -253,8 +247,8 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper if (isArrayIndex) { if (i >= m_storage->m_length) return false; - if (i < m_storage->m_vectorLength) { - JSValue value = m_storage->m_vector[i]; + if (i < m_vectorLength) { + JSValue& value = m_storage->m_vector[i]; if (value) { descriptor.setDescriptor(value, 0); return true; @@ -305,7 +299,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) m_storage->m_length = length; } - if (i < m_storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[i]; if (valueSlot) { valueSlot = value; @@ -313,8 +307,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) return; } valueSlot = value; - if (++m_storage->m_numValuesInVector == m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; checkConsistency(); return; } @@ -352,8 +345,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu if (increaseVectorLength(i + 1)) { storage = m_storage; storage->m_vector[i] = value; - if (++storage->m_numValuesInVector == storage->m_length) - m_fastAccessCutoff = storage->m_length; + ++storage->m_numValuesInVector; checkConsistency(); } else throwOutOfMemoryError(exec); @@ -363,7 +355,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Decide how many values it would be best to move from the map. unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; unsigned newVectorLength = increasedVectorLength(i + 1); - for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) + for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) newNumValuesInVector += map->contains(j); if (i >= MIN_SPARSE_ARRAY_INDEX) newNumValuesInVector -= map->contains(i); @@ -386,7 +378,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu return; } - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); @@ -404,7 +396,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu storage->m_vector[i] = value; - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; storage->m_numValuesInVector = newNumValuesInVector; m_storage = storage; @@ -431,7 +423,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) ArrayStorage* storage = m_storage; - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (!valueSlot) { checkConsistency(); @@ -439,8 +431,6 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) } valueSlot = JSValue(); --storage->m_numValuesInVector; - if (m_fastAccessCutoff > i) - m_fastAccessCutoff = i; checkConsistency(); return true; } @@ -472,7 +462,7 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); for (unsigned i = 0; i < usedVectorLength; ++i) { if (storage->m_vector[i]) propertyNames.add(Identifier::from(exec, i)); @@ -494,7 +484,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) ArrayStorage* storage = m_storage; - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; ASSERT(newLength > vectorLength); ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); unsigned newVectorLength = increasedVectorLength(newLength); @@ -503,7 +493,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) return false; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; for (unsigned i = vectorLength; i < newVectorLength; ++i) storage->m_vector[i] = JSValue(); @@ -521,10 +511,7 @@ void JSArray::setLength(unsigned newLength) unsigned length = m_storage->m_length; if (newLength < length) { - if (m_fastAccessCutoff > newLength) - m_fastAccessCutoff = newLength; - - unsigned usedVectorLength = min(length, storage->m_vectorLength); + unsigned usedVectorLength = min(length, m_vectorLength); for (unsigned i = newLength; i < usedVectorLength; ++i) { JSValue& valueSlot = storage->m_vector[i]; bool hadValue = valueSlot; @@ -563,20 +550,13 @@ JSValue JSArray::pop() JSValue result; - if (m_fastAccessCutoff > length) { - JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - ASSERT(result); - valueSlot = JSValue(); - --m_storage->m_numValuesInVector; - m_fastAccessCutoff = length; - } else if (length < m_storage->m_vectorLength) { + if (length < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - valueSlot = JSValue(); - if (result) + if (valueSlot) { --m_storage->m_numValuesInVector; - else + result = valueSlot; + valueSlot = JSValue(); + } else result = jsUndefined(); } else { result = jsUndefined(); @@ -604,11 +584,10 @@ void JSArray::push(ExecState* exec, JSValue value) { checkConsistency(); - if (m_storage->m_length < m_storage->m_vectorLength) { - ASSERT(!m_storage->m_vector[m_storage->m_length]); + if (m_storage->m_length < m_vectorLength) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -618,8 +597,8 @@ void JSArray::push(ExecState* exec, JSValue value) if (!map || map->isEmpty()) { if (increaseVectorLength(m_storage->m_length + 1)) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -837,7 +816,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (!m_storage->m_length) return; - unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items tree.abstractor().m_exec = exec; @@ -886,7 +865,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) { throwOutOfMemoryError(exec); @@ -926,7 +905,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) m_storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; m_storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -934,10 +912,16 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - args.append(getIndex(i)); + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + args.append(v); + } + for (; i < m_storage->m_length; ++i) args.append(get(exec, i)); } @@ -946,12 +930,17 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz { ASSERT(m_storage->m_length == maxSize); UNUSED_PARAM(maxSize); - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - buffer[i] = getIndex(i); - uint32_t size = m_storage->m_length; - for (; i < size; ++i) + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + buffer[i] = v; + } + + for (; i < m_storage->m_length; ++i) buffer[i] = get(exec, i); } @@ -961,7 +950,7 @@ unsigned JSArray::compactForSorting() ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); unsigned numDefined = 0; unsigned numUndefined = 0; @@ -985,7 +974,7 @@ unsigned JSArray::compactForSorting() if (SparseArrayValueMap* map = storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries - if not, // exception is thrown by caller. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) @@ -1006,7 +995,6 @@ unsigned JSArray::compactForSorting() for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -1032,30 +1020,27 @@ void JSArray::checkConsistency(ConsistencyCheckType type) if (type == SortConsistencyCheck) ASSERT(!m_storage->m_sparseValueMap); - ASSERT(m_fastAccessCutoff <= m_storage->m_length); - ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector); - unsigned numValuesInVector = 0; - for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) { + for (unsigned i = 0; i < m_vectorLength; ++i) { if (JSValue value = m_storage->m_vector[i]) { ASSERT(i < m_storage->m_length); if (type != DestructorConsistencyCheck) value->type(); // Likely to crash if the object was deallocated. ++numValuesInVector; } else { - ASSERT(i >= m_fastAccessCutoff); if (type == SortConsistencyCheck) ASSERT(i >= m_storage->m_numValuesInVector); } } ASSERT(numValuesInVector == m_storage->m_numValuesInVector); + ASSERT(numValuesInVector <= m_storage->m_length); if (m_storage->m_sparseValueMap) { SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end(); for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) { unsigned index = it->first; ASSERT(index < m_storage->m_length); - ASSERT(index >= m_storage->m_vectorLength); + ASSERT(index >= m_vectorLength); ASSERT(index <= MAX_ARRAY_INDEX); ASSERT(it->second); if (type != DestructorConsistencyCheck) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h index 12768a441c..8c224517cd 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h @@ -29,7 +29,6 @@ namespace JSC { struct ArrayStorage { unsigned m_length; - unsigned m_vectorLength; unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily. @@ -63,18 +62,24 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(); - bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; } + bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } JSValue getIndex(unsigned i) { ASSERT(canGetIndex(i)); return m_storage->m_vector[i]; } - bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; } - JSValue setIndex(unsigned i, JSValue v) + bool canSetIndex(unsigned i) { return i < m_vectorLength; } + void setIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); - return m_storage->m_vector[i] = v; + JSValue& x = m_storage->m_vector[i]; + if (!x) { + ++m_storage->m_numValuesInVector; + if (i >= m_storage->m_length) + m_storage->m_length = i + 1; + } + x = v; } void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -82,12 +87,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } inline void markChildrenDirect(MarkStack& markStack); protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); @@ -110,7 +116,7 @@ namespace JSC { enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - unsigned m_fastAccessCutoff; + unsigned m_vectorLength; ArrayStorage* m_storage; }; @@ -139,7 +145,7 @@ namespace JSC { ArrayStorage* storage = m_storage; - unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); if (SparseArrayValueMap* map = storage->m_sparseValueMap) { @@ -152,7 +158,7 @@ namespace JSC { inline void MarkStack::markChildren(JSCell* cell) { ASSERT(Heap::isCellMarked(cell)); - if (cell->structure()->typeInfo().hasDefaultMark()) { + if (!cell->structure()->typeInfo().overridesMarkChildren()) { #ifdef NDEBUG asObject(cell)->markChildrenDirect(*this); #else diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp index 90d39f0905..5e5003b188 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp @@ -45,7 +45,7 @@ JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) { - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark)); + PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); return result; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h index 006f4a2f7a..fe6e124d6f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h @@ -91,6 +91,9 @@ namespace JSC { WTF::ByteArray* storage() const { return m_storage.get(); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; + private: enum VPtrStealingHackType { VPtrStealingHack }; JSByteArray(VPtrStealingHackType) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp index aa9325269a..fae056eb7a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp @@ -78,11 +78,7 @@ extern const double Inf = NaNInf.doubles.Inf_Double; void* JSCell::operator new(size_t size, ExecState* exec) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocate(size); -#else return exec->heap()->allocate(size); -#endif } bool JSCell::getUInt32(uint32_t&) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h index 503c6c4093..722ae339ed 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h @@ -59,6 +59,7 @@ namespace JSC { virtual bool isGetterSetter() const; bool inherits(const ClassInfo*) const; virtual bool isAPIValueWrapper() const { return false; } + virtual bool isPropertyNameIterator() const { return false; } Structure* structure() const; @@ -112,14 +113,6 @@ namespace JSC { Structure* m_structure; }; - // FIXME: We should deprecate this and just use JSValue::asCell() instead. - JSCell* asCell(JSValue); - - inline JSCell* asCell(JSValue value) - { - return value.asCell(); - } - inline JSCell::JSCell(Structure* structure) : m_structure(structure) { @@ -162,11 +155,7 @@ namespace JSC { inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } // --- JSValue inlines ---------------------------- @@ -342,11 +331,6 @@ namespace JSC { append(value.asCell()); } - inline void Structure::markAggregate(MarkStack& markStack) - { - markStack.append(m_prototype); - } - inline Heap* Heap::heap(JSValue v) { if (!v.isCell()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h index a9ac63eabe..fcac9aaaa0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h @@ -61,17 +61,20 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } NativeFunction nativeFunction() { - return *reinterpret_cast<NativeFunction*>(m_data); + return *WTF::bitwise_cast<NativeFunction*>(m_data); } virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); + protected: + const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags; + private: JSFunction(NonNullPassRefPtr<Structure>); @@ -94,7 +97,7 @@ namespace JSC { ScopeChain& scopeChain() { ASSERT(!isHostFunctionNonInline()); - return *reinterpret_cast<ScopeChain*>(m_data); + return *WTF::bitwise_cast<ScopeChain*>(m_data); } void clearScopeChain() { @@ -109,11 +112,11 @@ namespace JSC { void setScopeChain(const ScopeChain& sc) { ASSERT(!isHostFunctionNonInline()); - *reinterpret_cast<ScopeChain*>(m_data) = sc; + *WTF::bitwise_cast<ScopeChain*>(m_data) = sc; } void setNativeFunction(NativeFunction func) { - *reinterpret_cast<NativeFunction*>(m_data) = func; + *WTF::bitwise_cast<NativeFunction*>(m_data) = func; } unsigned char m_data[sizeof(void*)]; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h index 3ad90ad8d1..d2aa2da436 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h @@ -30,6 +30,7 @@ #define JSGlobalData_h #include "Collector.h" +#include "DateInstanceCache.h" #include "ExecutableAllocator.h" #include "JITStubs.h" #include "JSValue.h" @@ -116,7 +117,8 @@ namespace JSC { const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark. SmallStrings smallStrings; NumericStrings numericStrings; - + DateInstanceCache dateInstanceCache; + #if ENABLE(ASSEMBLER) ExecutableAllocator executableAllocator; #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp index 3bb281ef15..cf3f1d175b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -89,7 +89,7 @@ static inline void markIfNeeded(MarkStack& markStack, JSValue v) static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) { if (s) - s->markAggregate(markStack); + markIfNeeded(markStack, s->storedPrototype()); } JSGlobalObject::~JSGlobalObject() @@ -394,6 +394,21 @@ void JSGlobalObject::markChildren(MarkStack& markStack) markIfNeeded(markStack, d()->methodCallDummy); markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->argumentsStructure); + markIfNeeded(markStack, d()->arrayStructure); + markIfNeeded(markStack, d()->booleanObjectStructure); + markIfNeeded(markStack, d()->callbackConstructorStructure); + markIfNeeded(markStack, d()->callbackFunctionStructure); + markIfNeeded(markStack, d()->callbackObjectStructure); + markIfNeeded(markStack, d()->dateStructure); + markIfNeeded(markStack, d()->emptyObjectStructure); + markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->functionStructure); + markIfNeeded(markStack, d()->numberObjectStructure); + markIfNeeded(markStack, d()->prototypeFunctionStructure); + markIfNeeded(markStack, d()->regExpMatchesArrayStructure); + markIfNeeded(markStack, d()->regExpStructure); + markIfNeeded(markStack, d()->stringObjectStructure); // No need to mark the other structures, because their prototypes are all // guaranteed to be referenced elsewhere. @@ -448,11 +463,7 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h index 2106783e22..720d3a56da 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h @@ -267,10 +267,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; + struct GlobalPropertyInfo { GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) : identifier(i) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h index 0d9aca6ef4..a271c4e494 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h @@ -62,10 +62,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + // JSValue methods virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h index 6a48081632..309488fed2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h @@ -68,23 +68,15 @@ namespace JSC { void* operator new(size_t size, ExecState* exec) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocateNumber(size); - #else return exec->heap()->allocateNumber(size); - #endif } void* operator new(size_t size, JSGlobalData* globalData) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocateNumber(size); - #else return globalData->heap.allocateNumber(size); - #endif } - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: JSNumberCell(JSGlobalData* globalData, double value) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h index 65c98036bd..ec3fa40966 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h @@ -41,11 +41,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } static void markStringifiers(MarkStack&, Stringifier*); + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp index db2a9b207e..6932deda97 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp @@ -42,6 +42,25 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSObject); +static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) +{ + // Add properties from the static hashtables of properties + for (; classInfo; classInfo = classInfo->parentClass) { + const HashTable* table = classInfo->propHashTable(exec); + if (!table) + continue; + table->initializeIfNeeded(exec); + ASSERT(table->table); + + int hashSizeMask = table->compactSize - 1; + const HashEntry* entry = table->table; + for (int i = 0; i <= hashSizeMask; ++i, ++entry) { + if (entry->key() && !(entry->attributes() & DontEnum)) + propertyNames.add(entry->key()); + } + } +} + void JSObject::markChildren(MarkStack& markStack) { #ifndef NDEBUG @@ -424,12 +443,29 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getEnumerablePropertyNames(exec, propertyNames, this); + getOwnPropertyNames(exec, propertyNames); + + if (prototype().isNull()) + return; + + JSObject* prototype = asObject(this->prototype()); + while(1) { + if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { + prototype->getPropertyNames(exec, propertyNames); + break; + } + prototype->getOwnPropertyNames(exec, propertyNames); + JSValue nextProto = prototype->prototype(); + if (nextProto.isNull()) + break; + prototype = asObject(nextProto); + } } void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getOwnEnumerablePropertyNames(exec, propertyNames, this); + m_structure->getEnumerablePropertyNames(propertyNames); + getEnumerablePropertyNames(exec, classInfo(), propertyNames); } bool JSObject::toBoolean(ExecState*) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h index 84b5f4b318..5a89c40a8a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h @@ -202,15 +202,17 @@ namespace JSC { void allocatePropertyStorageInline(size_t oldSize, size_t newSize); bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } - static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; - static const size_t nonInlineBaseStorageCapacity = 16; + static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; + static const unsigned nonInlineBaseStorageCapacity = 16; static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = 0; + void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { @@ -368,7 +370,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - if (structure()->typeInfo().hasStandardGetOwnPropertySlot()) + if (!structure()->typeInfo().overridesGetOwnPropertySlot()) return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot); return getOwnPropertySlot(exec, propertyName, slot); } @@ -682,7 +684,7 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) { JSCell::markChildren(markStack); - m_structure->markAggregate(markStack); + markStack.append(prototype()); PropertyStorage storage = propertyStorage(); size_t storageSize = m_structure->propertyStorageSize(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index e08a3d9e8e..6fd03446eb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -29,26 +29,61 @@ #include "config.h" #include "JSPropertyNameIterator.h" +#include "JSGlobalObject.h" + namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); -JSPropertyNameIterator::~JSPropertyNameIterator() +JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { + ASSERT(!o->structure()->enumerationCache() || + o->structure()->enumerationCache()->cachedStructure() != o->structure() || + o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); + + PropertyNameArray propertyNames(exec); + o->getPropertyNames(exec, propertyNames); + size_t numCacheableSlots = 0; + if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() && + !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames()) + numCacheableSlots = o->structure()->propertyStorageSize(); + + JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); + + if (o->structure()->isDictionary()) + return jsPropertyNameIterator; + + if (o->structure()->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + + size_t count = normalizePrototypeChain(exec, o); + StructureChain* structureChain = o->structure()->prototypeChain(exec); + RefPtr<Structure>* structure = structureChain->head(); + for (size_t i = 0; i < count; ++i) { + if (structure[i]->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + } + + jsPropertyNameIterator->setCachedPrototypeChain(structureChain); + jsPropertyNameIterator->setCachedStructure(o->structure()); + o->structure()->setEnumerationCache(jsPropertyNameIterator); + return jsPropertyNameIterator; } -void JSPropertyNameIterator::markChildren(MarkStack& markStack) +JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i) { - JSCell::markChildren(markStack); - if (m_object) - markStack.append(m_object); + JSValue& identifier = m_jsStrings[i]; + if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec)) + return identifier; + + if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value()))) + return JSValue(); + return identifier; } -void JSPropertyNameIterator::invalidate() +void JSPropertyNameIterator::markChildren(MarkStack& markStack) { - ASSERT(m_position == m_end); - m_object = 0; - m_data.clear(); + markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h index d2849a891b..529ae8b363 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -31,6 +31,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Operations.h" #include "PropertyNameArray.h" namespace JSC { @@ -39,73 +40,63 @@ namespace JSC { class JSObject; class JSPropertyNameIterator : public JSCell { + friend class JIT; + public: - static JSPropertyNameIterator* create(ExecState*, JSValue); + static JSPropertyNameIterator* create(ExecState*, JSObject*); + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren)); + } - virtual ~JSPropertyNameIterator(); + virtual bool isPropertyNameIterator() const { return true; } virtual void markChildren(MarkStack&); - JSValue next(ExecState*); - void invalidate(); - - static PassRefPtr<Structure> createStructure(JSValue prototype) + bool getOffset(size_t i, int& offset) { - return Structure::create(prototype, TypeInfo(CompoundType)); + if (i >= m_numCacheableSlots) + return false; + offset = i; + return true; } + + JSValue get(ExecState*, JSObject*, size_t i); + size_t size() { return m_jsStringsSize; } + + void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } + Structure* cachedStructure() { return m_cachedStructure; } + + void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } + StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } + private: - JSPropertyNameIterator(ExecState*); - JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); + JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot); - JSObject* m_object; - RefPtr<PropertyNameArrayData> m_data; - PropertyNameArrayData::const_iterator m_position; - PropertyNameArrayData::const_iterator m_end; + Structure* m_cachedStructure; + RefPtr<StructureChain> m_cachedPrototypeChain; + uint32_t m_numCacheableSlots; + uint32_t m_jsStringsSize; + OwnArrayPtr<JSValue> m_jsStrings; }; -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec) +inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots) : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(0) - , m_position(0) - , m_end(0) + , m_cachedStructure(0) + , m_numCacheableSlots(numCacheableSlots) + , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) + , m_jsStrings(new JSValue[m_jsStringsSize]) { + PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); + for (size_t i = 0; i < m_jsStringsSize; ++i) + m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring()); } -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData) - : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(object) - , m_data(propertyNameArrayData) - , m_position(m_data->begin()) - , m_end(m_data->end()) -{ -} - -inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v) +inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache) { - if (v.isUndefinedOrNull()) - return new (exec) JSPropertyNameIterator(exec); - - JSObject* o = v.toObject(exec); - PropertyNameArray propertyNames(exec); - o->getPropertyNames(exec, propertyNames); - return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData()); -} - -inline JSValue JSPropertyNameIterator::next(ExecState* exec) -{ - if (m_position == m_end) - return JSValue(); - - if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec)) - return jsOwnedString(exec, (*m_position++).ustring()); - - do { - if (m_object->hasProperty(exec, *m_position)) - return jsOwnedString(exec, (*m_position++).ustring()); - m_position++; - } while (m_position != m_end); - - return JSValue(); + ASSERT(!isDictionary()); + m_enumerationCache = enumerationCache; } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h index 5eb0e4b235..2542878064 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -57,7 +57,10 @@ namespace JSC{ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp index 91ddaebce7..20ba8684f6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp @@ -139,45 +139,4 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); } -JSString* jsString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s); -} - -JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) -{ - ASSERT(offset <= static_cast<unsigned>(s.size())); - ASSERT(length <= static_cast<unsigned>(s.size())); - ASSERT(offset + length <= static_cast<unsigned>(s.size())); - if (!length) - return globalData->smallStrings.emptyString(globalData); - if (length == 1) { - UChar c = s.data()[offset]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); -} - -JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h index 1e46551057..39dfe751cb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h @@ -92,7 +92,7 @@ namespace JSC { bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); } JSString* getIndex(JSGlobalData*, unsigned); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: enum VPtrStealingHackType { VPtrStealingHack }; @@ -169,6 +169,47 @@ namespace JSC { return jsSingleCharacterSubstring(globalData, m_value, i); } + inline JSString* jsString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s); + } + + inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) + { + ASSERT(offset <= static_cast<unsigned>(s.size())); + ASSERT(length <= static_cast<unsigned>(s.size())); + ASSERT(offset + length <= static_cast<unsigned>(s.size())); + if (!length) + return globalData->smallStrings.emptyString(globalData); + if (length == 1) { + UChar c = s.data()[offset]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); + } + + inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); + } + inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h index 279510bff3..7c8960071d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h @@ -40,9 +40,9 @@ namespace JSC { static const unsigned OverridesHasInstance = 1 << 2; static const unsigned ImplementsDefaultHasInstance = 1 << 3; static const unsigned NeedsThisConversion = 1 << 4; - static const unsigned HasStandardGetOwnPropertySlot = 1 << 5; - static const unsigned HasDefaultMark = 1 << 6; - static const unsigned HasDefaultGetPropertyNames = 1 << 7; + static const unsigned OverridesGetOwnPropertySlot = 1 << 5; + static const unsigned OverridesMarkChildren = 1 << 6; + static const unsigned OverridesGetPropertyNames = 1 << 7; class TypeInfo { friend class JIT; @@ -63,9 +63,9 @@ namespace JSC { bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; } bool overridesHasInstance() const { return m_flags & OverridesHasInstance; } bool needsThisConversion() const { return m_flags & NeedsThisConversion; } - bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; } - bool hasDefaultMark() const { return m_flags & HasDefaultMark; } - bool hasDefaultGetPropertyNames() const { return m_flags & HasDefaultGetPropertyNames; } + bool overridesGetOwnPropertySlot() const { return m_flags & OverridesGetOwnPropertySlot; } + bool overridesMarkChildren() const { return m_flags & OverridesMarkChildren; } + bool overridesGetPropertyNames() const { return m_flags & OverridesGetPropertyNames; } unsigned flags() const { return m_flags; } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 39a4093d46..699c1cd7cc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -110,7 +110,10 @@ char* JSValue::description() { static const size_t size = 32; static char description[size]; - if (isInt32()) + + if (!*this) + snprintf(description, size, "<JSValue()>"); + else if (isInt32()) snprintf(description, size, "Int32: %d", asInt32()); else if (isDouble()) snprintf(description, size, "Double: %lf", asDouble()); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h index 58e74b18c7..1063cdcd52 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h @@ -213,7 +213,8 @@ namespace JSC { enum { FalseTag = 0xfffffffc }; enum { NullTag = 0xfffffffb }; enum { UndefinedTag = 0xfffffffa }; - enum { DeletedValueTag = 0xfffffff9 }; + enum { EmptyValueTag = 0xfffffff9 }; + enum { DeletedValueTag = 0xfffffff8 }; enum { LowestTag = DeletedValueTag }; @@ -372,6 +373,14 @@ namespace JSC { return static_cast<uint32_t>(val); } + // FIXME: We should deprecate this and just use JSValue::asCell() instead. + JSCell* asCell(JSValue); + + inline JSCell* asCell(JSValue value) + { + return value.asCell(); + } + ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const { if (isInt32()) @@ -427,7 +436,7 @@ namespace JSC { inline JSValue::JSValue() { - u.asBits.tag = CellTag; + u.asBits.tag = EmptyValueTag; u.asBits.payload = 0; } @@ -463,19 +472,26 @@ namespace JSC { inline JSValue::JSValue(JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(ptr); } inline JSValue::JSValue(const JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr)); } inline JSValue::operator bool() const { - return u.asBits.payload || tag() != CellTag; + ASSERT(tag() != DeletedValueTag); + return tag() != EmptyValueTag; } inline bool JSValue::operator==(const JSValue& other) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h index 66e78c3851..d8b1479c03 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h @@ -60,10 +60,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags; // Subclasses of JSVariableObject can subclass this struct to add data // without increasing their own size (since there's a hard limit on the // size of a JSCell). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h index 723b75d440..191ff3b910 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h @@ -38,7 +38,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h index ba00057e02..ea09f5432b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h @@ -47,7 +47,7 @@ namespace JSC { } ALWAYS_INLINE void append(JSValue); - ALWAYS_INLINE void append(JSCell*); + void append(JSCell*); ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h index fee5ec5eb8..7f474b8298 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h @@ -37,8 +37,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h index 908c55f04b..cf19b6f962 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h @@ -39,11 +39,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h index ca3923d8fc..8223a90a38 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h @@ -30,17 +30,19 @@ namespace JSC { explicit NumberObject(NonNullPassRefPtr<Structure>); static const ClassInfo info; -#if USE(JSVALUE32) + static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: +#if USE(JSVALUE32) + static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; #else - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); - } + static const unsigned StructureFlags = JSWrapperObject::StructureFlags; #endif + private: virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp index a456423f1e..837d5a6f3c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -125,6 +125,7 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, return description; } +// FIXME: Use the enumeration cache. JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args) { if (!args.at(0).isObject()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h index 5da9e38390..1aa68b3a00 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h @@ -224,15 +224,15 @@ namespace JSC { return jsAddSlowCase(callFrame, v1, v2); } - inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot) + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase) { - JSCell* cell = asCell(baseValue); + JSCell* cell = asCell(base); size_t count = 0; - while (slot.slotBase() != cell) { + while (slotBase != cell) { JSValue v = cell->structure()->prototypeForLookup(callFrame); - // If we didn't find slotBase in baseValue's prototype chain, then baseValue + // If we didn't find slotBase in base's prototype chain, then base // must be a proxy for another object. if (v.isNull()) @@ -252,6 +252,25 @@ namespace JSC { return count; } + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base) + { + size_t count = 0; + while (1) { + JSValue v = base->structure()->prototypeForLookup(callFrame); + if (v.isNull()) + return count; + + base = asCell(v); + + // Since we're accessing a prototype in a loop, it's a good bet that it + // should not be treated as a dictionary. + if (base->structure()->isDictionary()) + asObject(base)->setStructure(Structure::fromDictionaryTransition(base->structure())); + + ++count; + } + } + ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain) { ScopeChainIterator iter = scopeChain->begin(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp index 0878e73f87..c28b6a4553 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -21,6 +21,9 @@ #include "config.h" #include "PropertyNameArray.h" +#include "Structure.h" +#include "StructureChain.h" + namespace JSC { static const size_t setThreshold = 20; @@ -44,7 +47,7 @@ void PropertyNameArray::add(UString::Rep* identifier) return; } - m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); + addKnownUnique(identifier); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h index afcc83ff05..3dbcc9df74 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h @@ -23,45 +23,35 @@ #include "CallFrame.h" #include "Identifier.h" -#include "Structure.h" #include <wtf/HashSet.h> +#include <wtf/OwnArrayPtr.h> #include <wtf/Vector.h> namespace JSC { + + class Structure; + class StructureChain; + // FIXME: Rename to PropertyNameArray. class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> { public: typedef Vector<Identifier, 20> PropertyNameVector; - typedef PropertyNameVector::const_iterator const_iterator; static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); } - const_iterator begin() const { return m_propertyNameVector.begin(); } - const_iterator end() const { return m_propertyNameVector.end(); } - PropertyNameVector& propertyNameVector() { return m_propertyNameVector; } - void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } - Structure* cachedStructure() const { return m_cachedStructure; } - - void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } - StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } - private: PropertyNameArrayData() - : m_cachedStructure(0) { } PropertyNameVector m_propertyNameVector; - Structure* m_cachedStructure; - RefPtr<StructureChain> m_cachedPrototypeChain; }; + // FIXME: Rename to PropertyNameArrayBuilder. class PropertyNameArray { public: - typedef PropertyNameArrayData::const_iterator const_iterator; - PropertyNameArray(JSGlobalData* globalData) : m_data(PropertyNameArrayData::create()) , m_globalData(globalData) @@ -82,21 +72,18 @@ namespace JSC { void add(UString::Rep*); void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } - size_t size() const { return m_data->propertyNameVector().size(); } - Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; } - const_iterator begin() const { return m_data->begin(); } - const_iterator end() const { return m_data->end(); } - void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; } PropertyNameArrayData* data() { return m_data.get(); } - PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } - void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; } - bool shouldCache() const { return m_shouldCache; } + // FIXME: Remove these functions. + typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator; + size_t size() const { return m_data->propertyNameVector().size(); } + const_iterator begin() const { return m_data->propertyNameVector().begin(); } + const_iterator end() const { return m_data->propertyNameVector().end(); } private: typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h index 224164d2f9..a0d5443dce 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h @@ -22,8 +22,8 @@ #ifndef Protect_h #define Protect_h -#include "JSCell.h" #include "Collector.h" +#include "JSValue.h" namespace JSC { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp index dbf2d44ae2..c609e083a3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -90,28 +90,6 @@ const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, @end */ -struct RegExpConstructorPrivate : FastAllocBase { - // Global search cache / settings - RegExpConstructorPrivate() - : lastNumSubPatterns(0) - , multiline(false) - , lastOvectorIndex(0) - { - } - - const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } - Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } - Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } - void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } - - UString input; - UString lastInput; - Vector<int, 32> ovector[2]; - unsigned lastNumSubPatterns : 30; - bool multiline : 1; - unsigned lastOvectorIndex : 1; -}; - RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype) : InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp")) , d(new RegExpConstructorPrivate) @@ -123,30 +101,6 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structur putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum); } -/* - To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular - expression matching through the performMatch function. We use cached results to calculate, - e.g., RegExp.lastMatch and RegExp.leftParen. -*/ -void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) -{ - position = r->match(s, startOffset, &d->tempOvector()); - - if (ovector) - *ovector = d->tempOvector().data(); - - if (position != -1) { - ASSERT(!d->tempOvector().isEmpty()); - - length = d->tempOvector()[1] - d->tempOvector()[0]; - - d->input = s; - d->lastInput = s; - d->changeLastOvector(); - d->lastNumSubPatterns = r->numSubpatterns(); - } -} - RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data) : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h index f8bccf4289..f9ca9cf1cd 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h @@ -22,6 +22,7 @@ #define RegExpConstructor_h #include "InternalFunction.h" +#include "RegExp.h" #include <wtf/OwnPtr.h> namespace JSC { @@ -30,13 +31,35 @@ namespace JSC { class RegExpPrototype; struct RegExpConstructorPrivate; + struct RegExpConstructorPrivate : FastAllocBase { + // Global search cache / settings + RegExpConstructorPrivate() + : lastNumSubPatterns(0) + , multiline(false) + , lastOvectorIndex(0) + { + } + + const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } + Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } + Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } + void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } + + UString input; + UString lastInput; + Vector<int, 32> ovector[2]; + unsigned lastNumSubPatterns : 30; + bool multiline : 1; + unsigned lastOvectorIndex : 1; + }; + class RegExpConstructor : public InternalFunction { public: RegExpConstructor(ExecState*, NonNullPassRefPtr<Structure>, RegExpPrototype*); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); @@ -59,6 +82,9 @@ namespace JSC { JSValue getLeftContext(ExecState*) const; JSValue getRightContext(ExecState*) const; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); @@ -78,6 +104,30 @@ namespace JSC { return static_cast<RegExpConstructor*>(asObject(value)); } + /* + To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular + expression matching through the performMatch function. We use cached results to calculate, + e.g., RegExp.lastMatch and RegExp.leftParen. + */ + inline void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) + { + position = r->match(s, startOffset, &d->tempOvector()); + + if (ovector) + *ovector = d->tempOvector().data(); + + if (position != -1) { + ASSERT(!d->tempOvector().isEmpty()); + + length = d->tempOvector()[1] - d->tempOvector()[0]; + + d->input = s; + d->lastInput = s; + d->changeLastOvector(); + d->lastNumSubPatterns = r->numSubpatterns(); + } + } + } // namespace JSC #endif // RegExpConstructor_h diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp index 877d7b6390..679d072ccf 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp @@ -159,7 +159,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args) } int position; - int length; + int length = 0; regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); if (position < 0) { d->lastIndex = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h index f5a9340561..3117c86fda 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h @@ -49,9 +49,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: bool match(ExecState*, const ArgList&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h index 944f6ba8f2..84e1ad24a0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h @@ -48,10 +48,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags; StringObject(NonNullPassRefPtr<Structure>, JSString*); }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index 0cba83d5cb..69e1939635 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h @@ -44,9 +44,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags; + virtual bool toBoolean(ExecState*) const { return false; } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp index b57732abe7..a0713b8dda 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp @@ -25,6 +25,7 @@ #include "CachedCall.h" #include "Error.h" #include "Executable.h" +#include "JSGlobalObjectFunctions.h" #include "JSArray.h" #include "JSFunction.h" #include "ObjectPrototype.h" @@ -72,6 +73,10 @@ static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSVa static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*, JSObject*, JSValue, const ArgList&); + } #include "StringPrototype.lut.h" @@ -117,6 +122,9 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec fontsize stringProtoFuncFontsize DontEnum|Function 1 anchor stringProtoFuncAnchor DontEnum|Function 1 link stringProtoFuncLink DontEnum|Function 1 + trim stringProtoFuncTrim DontEnum|Function 0 + trimLeft stringProtoFuncTrimLeft DontEnum|Function 0 + trimRight stringProtoFuncTrimRight DontEnum|Function 0 @end */ @@ -249,7 +257,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue return jsNull(); while (true) { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -290,7 +298,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue } else { do { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -485,7 +493,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); if (!(reg->global())) { // case without 'g' flag is handled like RegExp.prototype.exec @@ -535,7 +543,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); return jsNumber(exec, pos); } @@ -899,4 +907,51 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th return jsNontrivialString(exec, UString(buffer, bufferSize, false)); } +enum { + TrimLeft = 1, + TrimRight = 2 +}; + +static inline bool isTrimWhitespace(UChar c) +{ + return isStrWhiteSpace(c) || c == 0x200b; +} + +static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind) +{ + UString str = thisValue.toThisString(exec); + int left = 0; + if (trimKind & TrimLeft) { + while (left < str.size() && isTrimWhitespace(str[left])) + left++; + } + int right = str.size(); + if (trimKind & TrimRight) { + while (right > left && isTrimWhitespace(str[right - 1])) + right--; + } + + // Don't gc allocate a new string if we don't have to. + if (left == 0 && right == str.size() && thisValue.isString()) + return thisValue; + + return jsString(exec, str.substr(left, right - left)); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft | TrimRight); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimRight); +} + + } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp index 7209b5fe0e..65b62f9532 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp @@ -28,9 +28,10 @@ #include "Identifier.h" #include "JSObject.h" +#include "JSPropertyNameIterator.h" +#include "Lookup.h" #include "PropertyNameArray.h" #include "StructureChain.h" -#include "Lookup.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/RefPtr.h> @@ -159,9 +160,9 @@ Structure::~Structure() m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); } - - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); + + if (m_enumerationCache) + m_enumerationCache->setCachedStructure(0); if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; @@ -282,59 +283,6 @@ void Structure::materializePropertyMap() } } -void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - getEnumerableNamesFromPropertyTable(propertyNames); - getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); -} - -void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); - - if (shouldCache && m_cachedPropertyNameArrayData) { - if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { - propertyNames.setData(m_cachedPropertyNameArrayData); - return; - } - clearEnumerationCache(); - } - - baseObject->getOwnPropertyNames(exec, propertyNames); - - if (m_prototype.isObject()) { - propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. - JSObject* prototype = asObject(m_prototype); - while(1) { - if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames); - break; - } - prototype->getOwnPropertyNames(exec, propertyNames); - JSValue nextProto = prototype->prototype(); - if (!nextProto.isObject()) - break; - prototype = asObject(nextProto); - } - } - - if (shouldCache) { - StructureChain* protoChain = prototypeChain(exec); - m_cachedPropertyNameArrayData = propertyNames.data(); - if (!protoChain->isCacheable()) - return; - m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain); - m_cachedPropertyNameArrayData->setCachedStructure(this); - } -} - -void Structure::clearEnumerationCache() -{ - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); - m_cachedPropertyNameArrayData.clear(); -} - void Structure::growPropertyStorageCapacity() { if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) @@ -427,6 +375,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_specificValueInPrevious = specificValue; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -469,6 +418,7 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -485,6 +435,7 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -516,6 +467,7 @@ PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structur transition->m_specificValueInPrevious = 0; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -544,6 +496,7 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo()); transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -562,6 +515,7 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di transition->m_dictionaryKind = kind; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; structure->materializePropertyMapIfNecessary(); transition->m_propertyTable = structure->copyPropertyTable(); @@ -598,25 +552,28 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; + if (attributes & DontEnum) + m_hasNonEnumerableProperties = true; + size_t offset = put(propertyName, attributes, specificValue); if (propertyStorageSize() > propertyStorageCapacity()) growPropertyStorageCapacity(); - clearEnumerationCache(); return offset; } size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { ASSERT(isUncacheableDictionary()); + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = remove(propertyName); - clearEnumerationCache(); return offset; } @@ -1057,7 +1014,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b) return 0; } -void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames) +void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -1114,25 +1071,6 @@ void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyN } } -void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) -{ - // Add properties from the static hashtables of properties - for (; classInfo; classInfo = classInfo->parentClass) { - const HashTable* table = classInfo->propHashTable(exec); - if (!table) - continue; - table->initializeIfNeeded(exec); - ASSERT(table->table); - - int hashSizeMask = table->compactSize - 1; - const HashEntry* entry = table->table; - for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && !(entry->attributes() & DontEnum)) - propertyNames.add(entry->key()); - } - } -} - #if DO_PROPERTYMAP_CONSTENCY_CHECK void Structure::checkConsistency() diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index ed9f6e5985..f355c532d4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -30,6 +30,8 @@ #include "JSType.h" #include "JSValue.h" #include "PropertyMapHashTable.h" +#include "PropertyNameArray.h" +#include "Protect.h" #include "StructureChain.h" #include "StructureTransitionTable.h" #include "JSTypeInfo.h" @@ -76,8 +78,6 @@ namespace JSC { ~Structure(); - void markAggregate(MarkStack&); - // These should be used with caution. size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t removePropertyWithoutTransition(const Identifier& propertyName); @@ -95,8 +95,8 @@ namespace JSC { Structure* previousID() const { return m_previous.get(); } void growPropertyStorageCapacity(); - size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; } - size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } + unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; } + unsigned propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } bool isUsingInlineStorage() const; size_t get(const Identifier& propertyName); @@ -116,17 +116,22 @@ namespace JSC { return hasTransition(propertyName._ustring.rep(), attributes); } - void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } + bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } + + bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; } + bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } JSCell* specificValue() { return m_specificValueInPrevious; } void despecifyDictionaryFunction(const Identifier& propertyName); + void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. + JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); } + void getEnumerablePropertyNames(PropertyNameArray&); + private: Structure(JSValue prototype, const TypeInfo&); @@ -140,8 +145,6 @@ namespace JSC { size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); void addAnonymousSlots(unsigned slotCount); - void getEnumerableNamesFromPropertyTable(PropertyNameArray&); - void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&); void expandPropertyMapHashTable(); void rehashPropertyMapHashTable(); @@ -162,8 +165,6 @@ namespace JSC { materializePropertyMap(); } - void clearEnumerationCache(); - signed char transitionCount() const { // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both. @@ -189,16 +190,17 @@ namespace JSC { StructureTransitionTable table; - RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; + ProtectedPtr<JSPropertyNameIterator> m_enumerationCache; PropertyMapHashTable* m_propertyTable; - size_t m_propertyStorageCapacity; + uint32_t m_propertyStorageCapacity; signed char m_offset; unsigned m_dictionaryKind : 2; bool m_isPinnedPropertyTable : 1; bool m_hasGetterSetterProperties : 1; + bool m_hasNonEnumerableProperties : 1; #if COMPILER(WINSCW) // Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared // bitfield, when used as argument in make_pair() function calls in structure.ccp. diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp index 6e8a0ee256..085876c496 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp @@ -46,18 +46,4 @@ StructureChain::StructureChain(Structure* head) m_vector[i] = 0; } -bool StructureChain::isCacheable() const -{ - uint32_t i = 0; - - while (m_vector[i]) { - // Both classes of dictionary structure may change arbitrarily so we can't cache them - if (m_vector[i]->isDictionary()) - return false; - if (!m_vector[i++]->typeInfo().hasDefaultGetPropertyNames()) - return false; - } - return true; -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h index c48749d29b..816b66d505 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h @@ -36,10 +36,11 @@ namespace JSC { class Structure; class StructureChain : public RefCounted<StructureChain> { + friend class JIT; + public: static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); } RefPtr<Structure>* head() { return m_vector.get(); } - bool isCacheable() const; private: StructureChain(Structure* head); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h index 7bfa6d0830..5925641f80 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h @@ -40,6 +40,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/src/3rdparty/webkit/JavaScriptCore/wscript b/src/3rdparty/webkit/JavaScriptCore/wscript index 9dd37c960a..7a5ba1bca6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wscript +++ b/src/3rdparty/webkit/JavaScriptCore/wscript @@ -30,7 +30,7 @@ import commands from settings import * jscore_excludes = ['jsc.cpp', 'ucptable.cpp', 'GOwnPtr.cpp'] -jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp'])) +jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp'])) sources = [] diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h b/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h index 6a0521121e..f682f0d71d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h @@ -70,10 +70,6 @@ namespace WTF { return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef()); } -#ifndef NDEBUG - bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); } -#endif - private: CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter) : m_threadSafeRefCounter(threadedCounter) @@ -92,6 +88,10 @@ namespace WTF { void threadSafeDeref(); +#ifndef NDEBUG + bool isOwnedByCurrentThread() const { return !m_threadId || m_threadId == currentThread(); } +#endif + RefCountedBase m_refCounter; ThreadSafeSharedBase* m_threadSafeRefCounter; T* m_data; @@ -103,7 +103,7 @@ namespace WTF { template<class T> void CrossThreadRefCounted<T>::ref() { - ASSERT(!m_threadId || m_threadId == currentThread()); + ASSERT(isOwnedByCurrentThread()); m_refCounter.ref(); #ifndef NDEBUG // Store the threadId as soon as the ref count gets to 2. @@ -119,7 +119,7 @@ namespace WTF { template<class T> void CrossThreadRefCounted<T>::deref() { - ASSERT(!m_threadId || m_threadId == currentThread()); + ASSERT(isOwnedByCurrentThread()); if (m_refCounter.derefBase()) { threadSafeDeref(); delete this; @@ -146,10 +146,12 @@ namespace WTF { template<class T> PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy() { + ASSERT(isOwnedByCurrentThread()); if (m_threadSafeRefCounter) m_threadSafeRefCounter->ref(); else m_threadSafeRefCounter = new ThreadSafeSharedBase(2); + return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/CurrentTime.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/CurrentTime.cpp index a3d52906e2..b36cae5abb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/CurrentTime.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/CurrentTime.cpp @@ -63,6 +63,10 @@ extern "C" time_t mktime(struct tm *t); #include <sys/time.h> #endif +#if PLATFORM(CHROMIUM) +#error Chromium uses a different timer implementation +#endif + namespace WTF { const double msPerSecond = 1000.0; diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp index 0386494941..2110432c31 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp @@ -501,13 +501,13 @@ double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bo return result; } +// input is UTC void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) { - // input is UTC double dstOff = 0.0; - const double utcOff = getUTCOffset(); - - if (!outputIsUTC) { // convert to local time + double utcOff = 0.0; + if (!outputIsUTC) { + utcOff = getUTCOffset(); dstOff = getDSTOffset(ms, utcOff); ms += dstOff + utcOff; } @@ -522,8 +522,7 @@ void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; tm.isDST = dstOff != 0.0; - - tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond); + tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond); tm.timeZone = NULL; } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp index a9472c98d5..6cd8ef055e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp @@ -379,6 +379,9 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #include <stdarg.h> #include <stddef.h> #include <stdio.h> +#if PLATFORM(UNIX) +#include <unistd.h> +#endif #if COMPILER(MSVC) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -391,6 +394,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #if PLATFORM(DARWIN) #include "MallocZoneSupport.h" #include <wtf/HashSet.h> +#include <wtf/Vector.h> #endif #ifndef PRIuS @@ -2274,7 +2278,7 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -#if PLATFORM(WIN) +#if PLATFORM(WIN_OS) static void sleep(unsigned seconds) { ::Sleep(seconds * 1000); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h index b23e7b0a1b..541b05d3af 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h @@ -26,13 +26,19 @@ #include <stdlib.h> #include <new> +#if COMPILER(GCC) +#define WTF_FAST_MALLOC_EXPORT __attribute__((visibility("default"))) +#else +#define WTF_FAST_MALLOC_EXPORT +#endif + namespace WTF { // These functions call CRASH() if an allocation fails. - void* fastMalloc(size_t); + void* fastMalloc(size_t) WTF_FAST_MALLOC_EXPORT; void* fastZeroedMalloc(size_t); - void* fastCalloc(size_t numElements, size_t elementSize); - void* fastRealloc(void*, size_t); + void* fastCalloc(size_t numElements, size_t elementSize) WTF_FAST_MALLOC_EXPORT; + void* fastRealloc(void*, size_t) WTF_FAST_MALLOC_EXPORT; struct TryMallocReturnValue { TryMallocReturnValue(void* data) @@ -71,7 +77,7 @@ namespace WTF { TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size); TryMallocReturnValue tryFastRealloc(void* p, size_t n); - void fastFree(void*); + void fastFree(void*) WTF_FAST_MALLOC_EXPORT; #ifndef NDEBUG void fastMallocForbid(); @@ -213,6 +219,9 @@ using WTF::fastMallocAllow; // debug-only code to make sure we don't use the system malloc via the default operator // new by accident. +// We musn't customize the global operator new and delete for the Qt port. +#if !PLATFORM(QT) + WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); } WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); } @@ -224,4 +233,6 @@ WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw( #endif +#endif + #endif /* WTF_FastMalloc_h */ diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h index d863226b01..8bf6447446 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h @@ -44,6 +44,9 @@ namespace WTF { template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } }; + // Remove inline for winscw compiler to prevent the compiler agressively resolving + // T::ref() in RefPtr<T>'s copy constructor. The bug is reported at: + // https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812. template <typename T> #if !COMPILER(WINSCW) inline diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h index 324300d3a1..556230eb8c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h @@ -102,6 +102,8 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x #if COMPILER(MSVC) || COMPILER(RVCT) +inline long long llround(double num) { return static_cast<long long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } +inline long long llroundf(float num) { return static_cast<long long>(num > 0 ? num + 0.5f : ceil(num - 0.5f)); } inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); } inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/MessageQueue.h b/src/3rdparty/webkit/JavaScriptCore/wtf/MessageQueue.h index 12291cc318..9c9a4a789a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/MessageQueue.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/MessageQueue.h @@ -55,9 +55,13 @@ namespace WTF { bool waitForMessage(DataType&); template<typename Predicate> MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime); - void kill(); + + template<typename Predicate> + void removeIf(Predicate&); bool tryGetMessage(DataType&); + + void kill(); bool killed() const; // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time. @@ -149,6 +153,17 @@ namespace WTF { } template<typename DataType> + template<typename Predicate> + inline void MessageQueue<DataType>::removeIf(Predicate& predicate) + { + MutexLocker lock(m_mutex); + DequeConstIterator<DataType> found = m_queue.end(); + while ((found = m_queue.findIf(predicate)) != m_queue.end()) { + m_queue.remove(found); + } + } + + template<typename DataType> inline bool MessageQueue<DataType>::isEmpty() { MutexLocker lock(m_mutex); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h index 9fbfa85ef9..cb6c9b92e0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h @@ -231,40 +231,94 @@ #if defined(arm) \ || defined(__arm__) #define WTF_PLATFORM_ARM 1 + #if defined(__ARMEB__) #define WTF_PLATFORM_BIG_ENDIAN 1 -#elif !defined(__ARM_EABI__) && !defined(__EABI__) && !defined(__VFP_FP__) + +#elif !defined(__ARM_EABI__) \ + && !defined(__EABI__) \ + && !defined(__VFP_FP__) #define WTF_PLATFORM_MIDDLE_ENDIAN 1 + #endif -#define ARM_ARCH_VERSION 3 -#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__MARM_ARMV4__) \ - || defined(_ARMV4I_) -#undef ARM_ARCH_VERSION + +/* Set ARM_ARCH_VERSION */ +#if defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) \ + || defined(__MARM_ARMV4__) \ + || defined(_ARMV4I_) #define ARM_ARCH_VERSION 4 -#endif -#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ - || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) || defined(__MARM_ARMV5__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) \ + || defined(__MARM_ARMV5__) #define ARM_ARCH_VERSION 5 -#endif -#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) || defined(__ARMV6__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARMV6__) #define ARM_ARCH_VERSION 6 -#endif -#if defined(__ARM_ARCH_7A__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) #define ARM_ARCH_VERSION 7 + +/* RVCT sets _TARGET_ARCH_ARM */ +#elif defined(__TARGET_ARCH_ARM) +#define ARM_ARCH_VERSION __TARGET_ARCH_ARM + +#else +#define ARM_ARCH_VERSION 0 + #endif + +/* Set THUMB_ARM_VERSION */ +#if defined(__ARM_ARCH_4T__) +#define THUMB_ARCH_VERSION 1 + +#elif defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +#define THUMB_ARCH_VERSION 2 + +#elif defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) +#define THUMB_ARCH_VERSION 3 + +#elif defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) +#define THUMB_ARCH_VERSION 4 + +/* RVCT sets __TARGET_ARCH_THUMB */ +#elif defined(__TARGET_ARCH_THUMB) +#define THUMB_ARCH_VERSION __TARGET_ARCH_THUMB + +#else +#define THUMB_ARCH_VERSION 0 +#endif + /* On ARMv5 and below the natural alignment is required. */ #if !defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_ARCH_VERSION <= 5 #define ARM_REQUIRE_NATURAL_ALIGNMENT 1 #endif + /* Defines two pseudo-platforms for ARM and Thumb-2 instruction set. */ #if !defined(WTF_PLATFORM_ARM_TRADITIONAL) && !defined(WTF_PLATFORM_ARM_THUMB2) -# if defined(thumb2) || defined(__thumb2__) +# if defined(thumb2) || defined(__thumb2__) \ + || ((defined(__thumb) || defined(__thumb__)) && THUMB_ARCH_VERSION == 4) # define WTF_PLATFORM_ARM_TRADITIONAL 0 # define WTF_PLATFORM_ARM_THUMB2 1 # elif PLATFORM_ARM_ARCH(4) @@ -316,6 +370,12 @@ # if Q_BYTE_ORDER == Q_BIG_EDIAN # define WTF_PLATFORM_BIG_ENDIAN 1 # endif + +# include <ce_time.h> +#endif + +#if PLATFORM(WINCE) && PLATFORM(QT) +# include <ce_time.h> #endif /* Compiler */ @@ -412,6 +472,7 @@ #if PLATFORM(MAC) && !PLATFORM(IPHONE) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && defined(__x86_64__) #define WTF_USE_PLUGIN_HOST_PROCESS 1 #endif @@ -428,6 +489,7 @@ #if PLATFORM(CHROMIUM) && PLATFORM(DARWIN) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #if PLATFORM(IPHONE) @@ -444,6 +506,7 @@ #define HAVE_READLINE 1 #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #if PLATFORM(WIN) @@ -457,6 +520,7 @@ #if PLATFORM(GTK) #if HAVE(PTHREAD_H) #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #endif @@ -464,6 +528,7 @@ #define HAVE_POSIX_MEMALIGN 1 #define WTF_USE_CURL 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #define USE_SYSTEM_MALLOC 1 #define ENABLE_NETSCAPE_PLUGIN_API 0 #endif @@ -497,7 +562,7 @@ #define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIMEB_H 1 -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) && !PLATFORM(QT) #define HAVE_MADV_FREE_REUSE 1 #define HAVE_MADV_FREE 1 #define HAVE_PTHREAD_SETNAME_NP 1 @@ -644,7 +709,7 @@ #endif #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) -#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX)) +#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX) || PLATFORM(WIN_OS)) #define WTF_USE_JSVALUE64 1 #elif PLATFORM(ARM) || PLATFORM(PPC64) #define WTF_USE_JSVALUE32 1 @@ -671,8 +736,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 #elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) - /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ - #define ENABLE_JIT 0 + #define ENABLE_JIT 1 #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 /* The JIT is tested & working on x86 Windows */ #elif PLATFORM(X86) && PLATFORM(WIN) @@ -738,8 +802,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */ #if (PLATFORM(X86) && PLATFORM(MAC)) \ || (PLATFORM(X86_64) && PLATFORM(MAC)) \ - /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \ - || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) && 0) \ + || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE)) \ || (PLATFORM(X86) && PLATFORM(WIN)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 @@ -805,6 +868,10 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WARN_UNUSED_RETURN #endif +#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((PLATFORM(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK))) +#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1 +#endif + /* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */ #define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp index 0e6e20830d..52fb13084e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp @@ -82,6 +82,23 @@ double randomNumber() return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); #elif PLATFORM(WINCE) return genrand_res53(); +#elif PLATFORM(WIN_OS) + uint32_t part1 = rand() & (RAND_MAX - 1); + uint32_t part2 = rand() & (RAND_MAX - 1); + uint32_t part3 = rand() & (RAND_MAX - 1); + uint32_t part4 = rand() & (RAND_MAX - 1); + // rand only provides 15 bits on Win32 + uint64_t fullRandom = part1; + fullRandom <<= 15; + fullRandom |= part2; + fullRandom <<= 15; + fullRandom |= part3; + fullRandom <<= 15; + fullRandom |= part4; + + // Mask off the low 53bits + fullRandom &= (1LL << 53) - 1; + return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); #else uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/StdLibExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/StdLibExtras.h index d21d1ffccf..c9b574251b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/StdLibExtras.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/StdLibExtras.h @@ -32,6 +32,7 @@ // Use these to declare and define a static local variable (static T;) so that // it is leaked so that its destructors are not called at exit. Using this // macro also allows workarounds a compiler bug present in Apple's version of GCC 4.0.1. +#ifndef DEFINE_STATIC_LOCAL #if COMPILER(GCC) && defined(__APPLE_CC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 1 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ static type* name##Ptr = new type arguments; \ @@ -40,6 +41,7 @@ #define DEFINE_STATIC_LOCAL(type, name, arguments) \ static type& name = *new type arguments #endif +#endif // OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes. // The magic number 0x4000 is insignificant. We use it to avoid using NULL, since diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h index 559e3f2ffe..1120d65473 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h @@ -75,12 +75,12 @@ inline char* strdup(const char* strSource) inline int strncasecmp(const char* s1, const char* s2, size_t len) { - return strnicmp(s1, s2, len); + return _strnicmp(s1, s2, len); } inline int strcasecmp(const char* s1, const char* s2) { - return stricmp(s1, s2); + return _stricmp(s1, s2); } #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.cpp index 56bf43814f..1d4185ccea 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.cpp @@ -51,7 +51,7 @@ static void* threadEntryPoint(void* contextData) setThreadNameInternal(context->name); - // Block until our creating thread has completed any extra setup work + // Block until our creating thread has completed any extra setup work. { MutexLocker locker(context->creationMutex); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h index 515454517d..71c940261f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h @@ -128,7 +128,11 @@ void detachThread(ThreadIdentifier); #if USE(PTHREADS) typedef pthread_mutex_t PlatformMutex; +#if HAVE(PTHREAD_RWLOCK) typedef pthread_rwlock_t PlatformReadWriteLock; +#else +typedef void* PlatformReadWriteLock; +#endif typedef pthread_cond_t PlatformCondition; #elif PLATFORM(GTK) typedef GOwnPtr<GMutex> PlatformMutex; diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp index e4fb4198da..6cad5e3618 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -167,6 +167,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) { LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data); + delete threadData; return 0; } return establishIdentifierForPthreadHandle(threadHandle); @@ -270,7 +271,7 @@ void Mutex::unlock() ASSERT_UNUSED(result, !result); } - +#if HAVE(PTHREAD_RWLOCK) ReadWriteLock::ReadWriteLock() { pthread_rwlock_init(&m_readWriteLock, NULL); @@ -324,6 +325,7 @@ void ReadWriteLock::unlock() int result = pthread_rwlock_unlock(&m_readWriteLock); ASSERT_UNUSED(result, !result); } +#endif // HAVE(PTHREAD_RWLOCK) ThreadCondition::ThreadCondition() { diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp index aafea3cf9e..d0880866a3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -1490,7 +1490,7 @@ public: closeBodyAlternative(); } - void alterantiveBodyDisjunction() + void alternativeBodyDisjunction() { int newAlternativeIndex = m_bodyDisjunction->terms.size(); m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; @@ -1499,7 +1499,7 @@ public: m_currentAlternativeIndex = newAlternativeIndex; } - void alterantiveDisjunction() + void alternativeDisjunction() { int newAlternativeIndex = m_bodyDisjunction->terms.size(); m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; @@ -1515,9 +1515,9 @@ public: if (alt) { if (disjunction == m_pattern.m_body) - alterantiveBodyDisjunction(); + alternativeBodyDisjunction(); else - alterantiveDisjunction(); + alternativeDisjunction(); } PatternAlternative* alternative = disjunction->m_alternatives[alt]; diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp index d777424546..5ce579ab27 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp @@ -1264,7 +1264,7 @@ class RegexGenerator : private MacroAssembler { // complex here in compilation, and in the common case we should end up coallescing the checks. // // FIXME: a nice improvement here may be to stop trying to match sooner, based on the least - // of the minimum-alterantive-lengths. E.g. if I have two alternatives of length 200 and 150, + // of the minimum-alternative-lengths. E.g. if I have two alternatives of length 200 and 150, // and a string of length 100, we'll end up looping index from 0 to 100, checking whether there // is sufficient input to run either alternative (constantly failing). If there had been only // one alternative, or if the shorter alternative had come first, we would have terminated @@ -1309,9 +1309,6 @@ class RegexGenerator : private MacroAssembler { loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif #elif PLATFORM(ARM) -#if PLATFORM(ARM_TRADITIONAL) - push(ARMRegisters::lr); -#endif push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); @@ -1400,14 +1397,6 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const } } -int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize) -{ - if (JSRegExp* fallback = jitObject.getFallback()) - return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0]; - - return jitObject.execute(input, start, length, output); -} - }} #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h index 5b0df9dde0..1872f21009 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h @@ -82,7 +82,14 @@ private: }; void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false); -int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize); + +inline int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize) +{ + if (JSRegExp* fallback = jitObject.getFallback()) + return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0]; + + return jitObject.execute(input, start, length, output); +} } } // namespace JSC::Yarr |