diff options
author | Frans Englich <frans.englich@nokia.com> | 2009-09-24 16:58:05 (GMT) |
---|---|---|
committer | Frans Englich <frans.englich@nokia.com> | 2009-09-24 16:58:05 (GMT) |
commit | 90996b73d4f2983d6f721c205b5a0957d3a55aff (patch) | |
tree | 1ab4215df101422590c7af368cdd22d4f1dc3786 /src/3rdparty | |
parent | 9345d47c3945b61a27724508e8b3d0aaf7b57bcf (diff) | |
parent | aabd12223bda6260756ab19430082477d5669c0a (diff) | |
download | Qt-90996b73d4f2983d6f721c205b5a0957d3a55aff.zip Qt-90996b73d4f2983d6f721c205b5a0957d3a55aff.tar.gz Qt-90996b73d4f2983d6f721c205b5a0957d3a55aff.tar.bz2 |
Merge commit 'qt/4.6' into mmfphonon
Diffstat (limited to 'src/3rdparty')
747 files changed, 32792 insertions, 14868 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h index 762a15e..b6d1532 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h @@ -26,7 +26,7 @@ #ifndef APICast_h #define APICast_h -#include "JSNumberCell.h" +#include "JSAPIValueWrapper.h" #include "JSValue.h" #include <wtf/Platform.h> #include <wtf/UnusedParam.h> @@ -58,18 +58,18 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c) return reinterpret_cast<JSC::ExecState*>(c); } -inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v) +inline JSC::JSValue toJS(JSC::ExecState*, JSValueRef v) { - JSC::JSValue jsValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v))); -#if USE(ALTERNATE_JSIMMEDIATE) - UNUSED_PARAM(exec); +#if USE(JSVALUE32_64) + JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v)); + if (!jsCell) + return JSC::JSValue(); + if (jsCell->isAPIValueWrapper()) + return static_cast<JSC::JSAPIValueWrapper*>(jsCell)->value(); + return jsCell; #else - if (jsValue && jsValue.isNumber()) { - ASSERT(jsValue.isAPIMangledNumber()); - return JSC::jsNumber(exec, jsValue.uncheckedGetNumber()); - } + return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v))); #endif - return jsValue; } inline JSC::JSObject* toJS(JSObjectRef o) @@ -89,15 +89,16 @@ inline JSC::JSGlobalData* toJS(JSContextGroupRef g) inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v) { -#if USE(ALTERNATE_JSIMMEDIATE) - UNUSED_PARAM(exec); +#if USE(JSVALUE32_64) + if (!v) + return 0; + if (!v.isCell()) + return reinterpret_cast<JSValueRef>(asCell(JSC::jsAPIValueWrapper(exec, v))); + return reinterpret_cast<JSValueRef>(asCell(v)); #else - if (v && v.isNumber()) { - ASSERT(!v.isAPIMangledNumber()); - return reinterpret_cast<JSValueRef>(JSC::JSValue::encode(JSC::jsAPIMangledNumber(exec, v.uncheckedGetNumber()))); - } -#endif + UNUSED_PARAM(exec); return reinterpret_cast<JSValueRef>(JSC::JSValue::encode(v)); +#endif } inline JSObjectRef toRef(JSC::JSObject* o) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h index 9f3d88e..0a0dcda 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h @@ -64,10 +64,10 @@ typedef struct OpaqueJSValue* JSObjectRef; /* JavaScript symbol exports */ -#undef JS_EXPORT +#if !defined(JS_EXPORT) #if defined(BUILDING_WX__) #define JS_EXPORT -#elif defined(__GNUC__) +#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__) #define JS_EXPORT __attribute__((visibility("default"))) #elif defined(_WIN32_WCE) #if defined(JS_BUILDING_JS) @@ -90,6 +90,7 @@ typedef struct OpaqueJSValue* JSObjectRef; #else #define JS_EXPORT #endif +#endif #ifdef __cplusplus extern "C" { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h index 1f06249..0497aa2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h @@ -41,7 +41,7 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp index 1b3217b..b7dd768 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp @@ -28,6 +28,7 @@ #include "JSCallbackFunction.h" #include "APICast.h" +#include "CodeBlock.h" #include "JSFunction.h" #include "FunctionPrototype.h" #include <runtime/JSGlobalObject.h> diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h index 7dd87b5..3a17fa2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h +++ b/src/3rdparty/javascriptcore/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)); + return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h index 4360baa..e767cb5 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h @@ -66,7 +66,7 @@ private: virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); virtual double toNumber(ExecState*) const; virtual UString toString(ExecState*) const; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h index 669b3cd..c84c191 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h @@ -318,11 +318,12 @@ bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) { + JSValueRef valueRef = toRef(exec, value); JSValueRef exception = 0; bool result; { JSLock::DropAllLocks dropAllLocks(exec); - result = hasInstance(execRef, thisRef, toRef(exec, value), &exception); + result = hasInstance(execRef, thisRef, valueRef, &exception); } exec->setException(toJS(exec, exception)); return result; @@ -372,7 +373,7 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, } template <class Base> -void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { JSContextRef execRef = toRef(exec); JSObjectRef thisRef = toRef(this); @@ -380,7 +381,7 @@ void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) { JSLock::DropAllLocks dropAllLocks(exec); - getPropertyNames(execRef, thisRef, toRef(&propertyNames), listedAttributes); + getPropertyNames(execRef, thisRef, toRef(&propertyNames)); } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { @@ -406,7 +407,7 @@ void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray } } - Base::getPropertyNames(exec, propertyNames, listedAttributes); + Base::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } template <class Base> @@ -428,11 +429,13 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const JSLock::DropAllLocks dropAllLocks(exec); value = convertToType(ctx, thisRef, kJSTypeNumber, &exception); } - exec->setException(toJS(exec, exception)); - if (value) { - double dValue; - return toJS(exec, value).getNumber(dValue) ? dValue : NaN; + if (exception) { + exec->setException(toJS(exec, exception)); + return 0; } + + double dValue; + return toJS(exec, value).getNumber(dValue) ? dValue : NaN; } return Base::toNumber(exec); @@ -452,11 +455,11 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const JSLock::DropAllLocks dropAllLocks(exec); value = convertToType(ctx, thisRef, kJSTypeString, &exception); } - exec->setException(toJS(exec, exception)); - if (value) - return toJS(exec, value).getString(); - if (exception) + if (exception) { + exec->setException(toJS(exec, exception)); return ""; + } + return toJS(exec, value).getString(); } return Base::toString(exec); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h index c742d96..c4777dd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h @@ -58,7 +58,7 @@ struct StaticFunctionEntry : FastAllocBase { typedef HashMap<RefPtr<JSC::UString::Rep>, StaticValueEntry*> OpaqueJSClassStaticValuesTable; typedef HashMap<RefPtr<JSC::UString::Rep>, StaticFunctionEntry*> OpaqueJSClassStaticFunctionsTable; -class OpaqueJSClass; +struct OpaqueJSClass; // An OpaqueJSClass (JSClass) is created without a context, so it can be used with any context, even across context groups. // This structure holds data members that vary across context groups. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp index 87d36ec..06ef578 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp @@ -28,6 +28,7 @@ #include "JSObjectRef.h" #include "APICast.h" +#include "CodeBlock.h" #include "DateConstructor.h" #include "ErrorConstructor.h" #include "FunctionConstructor.h" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.h index 86921bd..3e8b0eb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.h @@ -187,7 +187,6 @@ typedef bool @param ctx The execution context to use. @param object The JSObject whose property names are being collected. @param accumulator A JavaScript property name accumulator in which to accumulate the names of object's properties. -@param flag Specify which property should be included @discussion If you named your function GetPropertyNames, you would declare it like this: void GetPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); @@ -197,7 +196,7 @@ Property name accumulators are used by JSObjectCopyPropertyNames and JavaScript Use JSPropertyNameAccumulatorAddName to add property names to accumulator. A class's getPropertyNames callback only needs to provide the names of properties that the class vends through a custom getProperty or setProperty callback. Other properties, including statically declared properties, properties vended by other classes, and properties belonging to object's prototype, are added independently. */ typedef void -(*JSObjectGetPropertyNamesCallback) (JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames, unsigned flag); +(*JSObjectGetPropertyNamesCallback) (JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); /*! @typedef JSObjectCallAsFunctionCallback diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h index 8b17ee2..41d8978 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h @@ -37,7 +37,7 @@ extern "C" { #endif -#if !defined(WIN32) && !defined(_WIN32) +#if (!defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__)) /*! @typedef JSChar @abstract A Unicode character. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog index 24fc7e7..20bfc23 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog +++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog @@ -1,3 +1,7264 @@ +2009-09-24 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Avoid __clear_cache built-in function if DISABLE_BUILTIN_CLEAR_CACHE define is set + https://bugs.webkit.org/show_bug.cgi?id=28886 + + There are some GCC packages (for example GCC-2006q3 from CodeSourcery) + which contain __clear_cache built-in function only for C while the C++ + version of __clear_cache is missing on ARM architectures. + + Fixed a small bug in the inline assembly of cacheFlush function on + ARM_TRADITIONAL. + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-09-21 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed make dist build fix. Missing files. + + * GNUmakefile.am: + +2009-09-19 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam 'Cabin Boy' Weinig. + + Fix stack alignment with ARM THUMB2 JIT. + https://bugs.webkit.org/show_bug.cgi?id=29526 + + Stack is currently being decremented by 0x3c, bump this to 0x40 to make this a + multiple of 16 bytes. + + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + * jit/JITStubs.h: + +2009-09-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + SNES is too slow + https://bugs.webkit.org/show_bug.cgi?id=29534 + + The problem was that the emulator used multiple classes with + more properties than our dictionary cutoff allowed, this resulted + in more or less all critical logic inside the emulator requiring + uncached property access. + + Rather than simply bumping the dictionary cutoff, this patch + recognises that there are two ways to create a "dictionary" + structure. Either by adding a large number of properties, or + by removing a property. In the case of adding properties we + know all the existing properties will maintain their existing + offsets, so we could cache access to those properties, if we + know they won't be removed. + + To make this possible, this patch adds the logic required to + distinguish a dictionary created by addition from one created + by removal. With this logic in place we can now cache access + to objects with large numbers of properties. + + SNES performance improved by more than 6x. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * runtime/BatchedTransitionOptimizer.h: + (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer): + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::getEnumerablePropertyNames): + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::removePropertyTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::toCacheableDictionaryTransition): + (JSC::Structure::toUncacheableDictionaryTransition): + (JSC::Structure::fromDictionaryTransition): + (JSC::Structure::removePropertyWithoutTransition): + * runtime/Structure.h: + (JSC::Structure::isDictionary): + (JSC::Structure::isUncacheableDictionary): + (JSC::Structure::): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Implement ES5 Object.create function + https://bugs.webkit.org/show_bug.cgi?id=29524 + + Implement Object.create. Very simple patch, effectively Object.defineProperties + only creating the target object itself. + + * runtime/CommonIdentifiers.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorCreate): + +2009-09-19 Dan Bernstein <mitz@apple.com> + + Fix clean debug builds. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-19 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by George Staikos. + + QtWebKit Windows CE compile fix + + https://bugs.webkit.org/show_bug.cgi?id=29379 + + There is no _aligned_alloc or _aligned_free on Windows CE. + We just use the Windows code that was there before and use VirtualAlloc. + But that also means that the BLOCK_SIZE must be 64K as this function + allocates on 64K boundaries. + + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlock): + * runtime/Collector.h: + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by Sam Weinig. + + Implement ES5 Object.defineProperties function + https://bugs.webkit.org/show_bug.cgi?id=29522 + + Implement Object.defineProperties. Fairly simple patch, simply makes use of + existing functionality used for defineProperty. + + * runtime/CommonIdentifiers.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::defineProperties): + (JSC::objectConstructorDefineProperties): + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Windows build fix part2 + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Buildfix). + + Windows build fix part 1. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-18 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Implement ES5 Object.defineProperty function + https://bugs.webkit.org/show_bug.cgi?id=29503 + + Implement Object.defineProperty. This requires adding the API to + ObjectConstructor, along with a helper function that implements the + ES5 internal [[ToPropertyDescriptor]] function. It then adds + JSObject::defineOwnProperty that implements the appropriate ES5 semantics. + Currently defineOwnProperty uses a delete followed by a put to redefine + attributes of a property, clearly this is less efficient than it could be + but we can improve this if it needs to be possible in future. + + * JavaScriptCore.exp: + * debugger/DebuggerActivation.cpp: + (JSC::DebuggerActivation::defineGetter): + (JSC::DebuggerActivation::defineSetter): + * debugger/DebuggerActivation.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + Update defineGetter/Setter calls + * runtime/CommonIdentifiers.h: + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::defineGetter): + (JSC::JSGlobalObject::defineSetter): + * runtime/JSGlobalObject.h: + * runtime/JSObject.cpp: + (JSC::JSObject::defineGetter): + (JSC::JSObject::defineSetter): + (JSC::putDescriptor): + (JSC::JSObject::defineOwnProperty): + * runtime/JSObject.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorGetOwnPropertyDescriptor): + (JSC::toPropertyDescriptor): + (JSC::objectConstructorDefineProperty): + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncDefineGetter): + (JSC::objectProtoFuncDefineSetter): + * runtime/PropertyDescriptor.cpp: + (JSC::PropertyDescriptor::writable): + (JSC::PropertyDescriptor::enumerable): + (JSC::PropertyDescriptor::configurable): + (JSC::PropertyDescriptor::isDataDescriptor): + (JSC::PropertyDescriptor::isGenericDescriptor): + (JSC::PropertyDescriptor::isAccessorDescriptor): + (JSC::PropertyDescriptor::getter): + (JSC::PropertyDescriptor::setter): + (JSC::PropertyDescriptor::setDescriptor): + (JSC::PropertyDescriptor::setAccessorDescriptor): + (JSC::PropertyDescriptor::setWritable): + (JSC::PropertyDescriptor::setEnumerable): + (JSC::PropertyDescriptor::setConfigurable): + (JSC::PropertyDescriptor::setSetter): + (JSC::PropertyDescriptor::setGetter): + (JSC::PropertyDescriptor::equalTo): + (JSC::PropertyDescriptor::attributesEqual): + (JSC::PropertyDescriptor::attributesWithOverride): + * runtime/PropertyDescriptor.h: + (JSC::PropertyDescriptor::PropertyDescriptor): + (JSC::PropertyDescriptor::value): + (JSC::PropertyDescriptor::setValue): + (JSC::PropertyDescriptor::isEmpty): + (JSC::PropertyDescriptor::writablePresent): + (JSC::PropertyDescriptor::enumerablePresent): + (JSC::PropertyDescriptor::configurablePresent): + (JSC::PropertyDescriptor::setterPresent): + (JSC::PropertyDescriptor::getterPresent): + (JSC::PropertyDescriptor::operator==): + (JSC::PropertyDescriptor::): + +2009-09-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Build fix to enable ARM_THUMB2 on Linux + https://bugs.webkit.org/show_bug.cgi?id= + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + * jit/JITStubs.cpp: + * wtf/Platform.h: + +2009-09-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + 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. + + * assembler/ARMAssembler.cpp: + * assembler/ARMAssembler.h: + * assembler/ARMv7Assembler.h: + * assembler/MacroAssembler.h: + * assembler/MacroAssemblerARM.cpp: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerCodeRef.h: + (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr): + * jit/ExecutableAllocator.h: + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::beginUninterruptedSequence): + (JSC::JIT::preserveReturnAddressAfterCall): + (JSC::JIT::restoreReturnAddressBeforeReturn): + (JSC::JIT::restoreArgumentReference): + (JSC::JIT::restoreArgumentReferenceForTrampoline): + * jit/JITOpcodes.cpp: + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + * jit/JITStubs.h: + * wtf/Platform.h: + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): + +2009-09-18 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by Simon Hausmann. + + Fix the Qt/Windows CE build. + + * JavaScriptCore.pri: Build the ce_time.cpp functions from + within Qt externally. + * wtf/DateMath.cpp: Removed unnecessary Qt #ifdef, for the + Qt build these functions are no external, too. + +2009-09-17 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + Symbian/WINSCW build fox. + + Repeat Q_OS_WIN wchar_t hack for WINSCW, similar to + revision 24774. + + WINSCW defines wchar_t, thus UChar has to be wchar_t + + * wtf/unicode/qt4/UnicodeQt4.h: + +2009-09-17 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + Symbian/WINSCW build fix. + + https://bugs.webkit.org/show_bug.cgi?id=29186 + + WINSCW Template specialisation name in declaration must the be the same as in implementation. + + * runtime/LiteralParser.h: + +2009-09-15 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=27060 + + Symbian compiler for emulator target (WINSCW) fails with + "illegal operand" for m_attributesInPrevious in structure.ccp + (when calling make_pair functions). + This error is apparently due to the compiler not properly + resolving the unsigned type of the declared bitfield. + + Initial patch explicitly casted m_attributesInPrevious + to unsigned, but since bitfield optimization is not critical for + the emulator target, this conditional change in header file + appears to be least intrusive. + + * runtime/Structure.h: + +2009-09-16 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Fix GCC warnings on ARM_THUMB2 platform + + * assembler/ARMv7Assembler.h: + (JSC::ARMThumbImmediate::countLeadingZerosPartial): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::branchTruncateDoubleToInt32): + (JSC::MacroAssemblerARMv7::moveFixedWidthEncoding): + +2009-09-16 Greg Bolsinga <bolsinga@apple.com> + + Add ENABLE(INSPECTOR) + https://bugs.webkit.org/show_bug.cgi?id=29260 + + Reviewed by David Kilzer. + + * wtf/Platform.h: + +2009-09-16 Greg Bolsinga <bolsinga@apple.com> + + Add ENABLE(CONTEXT_MENUS) + https://bugs.webkit.org/show_bug.cgi?id=29225 + + Reviewed by David Kilzer. + + * wtf/Platform.h: + +2009-09-16 Benjamin C Meyer <benjamin.meyer@torchmobile.com> + + Reviewed by Eric Seidel. + + The webkit stdint and stdbool headers exists because + the compiler MSVC doesn't include them. The check + should not check for PLATFORM(WIN_OS) but for MSVC. + + * os-win32/stdbool.h: + * os-win32/stdint.h: + +2009-09-16 Greg Bolsinga <bolsinga@apple.com> + + Add ENABLE(DRAG_SUPPORT) + https://bugs.webkit.org/show_bug.cgi?id=29233 + + Reviewed by David Kilzer. + + * wtf/Platform.h: + +2009-09-16 Kevin Ollivier <kevino@theolliviers.com> + + waf build fix after flag was moved to correct place. + + * wscript: + +2009-09-16 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Build fix for 64-bit Qt on Mac OS X + + * wtf/Platform.h: Use JSVALUE64 on DARWIN, not only on MAC + +2009-09-16 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + [Qt] Fix wtf/ThreadSpecific.h under Qt to free thread local objects. + https://bugs.webkit.org/show_bug.cgi?id=29295 + + This is an important fix when JavaScript workers are in use, since + unfreed ThreadGlobalDatas leak a big amount of memory (50-100k each). + QThreadStorage calls the destructor of a given object, which is the + ThreadSpecific::Data. Unlike pthread, Qt is object oriented, and does + not support the calling of a static utility function when the thread + is about to close. In this patch we call the ThreadSpecific::destroy() + utility function from the destructor of ThreadSpecific::Data. Moreover, + since Qt resets all thread local values to 0 before the calling of the + appropriate destructors, we set back the pointer to its original value. + This is necessary because the get() method of the ThreadSpecific + object may be called during the exuction of the destructor. + + * wtf/ThreadSpecific.h: + (WTF::ThreadSpecific::Data::~Data): + (WTF::::~ThreadSpecific): + (WTF::::set): + (WTF::::destroy): + +2009-09-10 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Allow anonymous storage inside JSObject + https://bugs.webkit.org/show_bug.cgi?id=29168 + + Add the concept of anonymous slots to Structures so that it is + possible to store references to values that need marking in the + standard JSObject storage buffer. This allows us to reduce the + malloc overhead of some objects (by allowing them to store JS + values in the inline storage of the object) and reduce the + dependence of custom mark functions (if all an objects children + are in the standard object property storage there's no need to + mark them manually). + + * JavaScriptCore.exp: + * runtime/JSObject.h: + (JSC::JSObject::putAnonymousValue): + (JSC::JSObject::getAnonymousValue): + (JSC::JSObject::addAnonymousSlots): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + (JSC::JSWrapperObject::JSWrapperObject): + (JSC::JSWrapperObject::setInternalValue): + * runtime/PropertyMapHashTable.h: + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::materializePropertyMap): + (JSC::Structure::addAnonymousSlotsTransition): + (JSC::Structure::copyPropertyTable): + (JSC::Structure::put): + (JSC::Structure::rehashPropertyMapHashTable): + * runtime/Structure.h: + (JSC::Structure::propertyStorageSize): + (JSC::StructureTransitionTable::reifySingleTransition): + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTable::TransitionTable::addSlotTransition): + (JSC::StructureTransitionTable::TransitionTable::removeSlotTransition): + (JSC::StructureTransitionTable::TransitionTable::getSlotTransition): + (JSC::StructureTransitionTable::getAnonymousSlotTransition): + (JSC::StructureTransitionTable::addAnonymousSlotTransition): + (JSC::StructureTransitionTable::removeAnonymousSlotTransition): + +2009-09-15 Alex Milowski <alex@milowski.com> + + Reviewed by Tor Arne Vestbø. + + Added the ENABLE_MATHML define to the features + + * Configurations/FeatureDefines.xcconfig: + +2009-09-15 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Build fix for windows. + + After http://trac.webkit.org/changeset/47795 the MinGW build broke, + because MinGW has __mingw_aligned_malloc instead of _aligned_malloc. + + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): MinGW case added. + (JSC::Heap::freeBlock): MinGW case added. + +2009-09-15 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Build fix for Windows/MinGW + + https://bugs.webkit.org/show_bug.cgi?id=29268 + + * wtf/Platform.h: JSVALUE32_64 temporarily disabled on PLATFORM(WIN_OS) with COMPILER(MINGW) + +2009-09-14 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Detect VFP at runtime in generic ARM port on Linux platform. + https://bugs.webkit.org/show_bug.cgi?id=29076 + + * JavaScriptCore.pri: + * assembler/MacroAssemblerARM.cpp: Added. + (JSC::isVFPPresent): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::supportsFloatingPoint): + +2009-09-14 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Build fix for windows build. + + * JavaScriptCore.pri: Correct a logic error. + * pcre/dftables: Add missing paranthesis for tmpdir function. + +2009-09-12 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Build fix for windows exports (again). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-12 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Build fix for windows exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-12 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Correct fix for non-allinonefile builds + + * runtime/ObjectConstructor.cpp: + +2009-09-12 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Fix non-allinonefile builds + + * runtime/ObjectConstructor.cpp: + +2009-09-12 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + [ES5] Implement Object.keys + https://bugs.webkit.org/show_bug.cgi?id=29170 + + This patch basically requires two separate steps, the first is to split getPropertyNames + into two functions -- getOwnPropertyNames and getPropertyNames, basically making them behave + in the same way as getOwnPropertySlot and getPropertySlot. In essence getOwnPropertyNames + produces the list of properties on an object excluding its prototype chain and getPropertyNames + just iterates the the object and its prototype chain calling getOwnPropertyNames at each level. + + * API/JSCallbackObject.h: + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * JavaScriptCore.exp: + * debugger/DebuggerActivation.cpp: + (JSC::DebuggerActivation::getOwnPropertyNames): + * debugger/DebuggerActivation.h: + * runtime/CommonIdentifiers.h: + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertyNames): + * runtime/JSArray.h: + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::getOwnPropertyNames): + * runtime/JSByteArray.h: + * runtime/JSNotAnObject.cpp: + (JSC::JSNotAnObject::getOwnPropertyNames): + * runtime/JSNotAnObject.h: + * runtime/JSObject.cpp: + (JSC::JSObject::getOwnPropertyNames): + * runtime/JSObject.h: + * runtime/JSVariableObject.cpp: + (JSC::JSVariableObject::getOwnPropertyNames): + * runtime/JSVariableObject.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorKeys): + * runtime/RegExpMatchesArray.h: + (JSC::RegExpMatchesArray::getOwnPropertyNames): + * runtime/StringObject.cpp: + (JSC::StringObject::getOwnPropertyNames): + * runtime/StringObject.h: + * runtime/Structure.cpp: + (JSC::Structure::getOwnEnumerablePropertyNames): + (JSC::Structure::getEnumerablePropertyNames): + * runtime/Structure.h: + +2009-09-11 Oliver Hunt <oliver@apple.com> + + Reviewed by Sam Weinig. + + getPropertyNames caching is invalid when the prototype chain contains objects with custom getPropertyNames + https://bugs.webkit.org/show_bug.cgi?id=29214 + + Add a flag to TypeInfo to indicate whether a type overrides getPropertyNames. + This flag is used to make sure that caching of the property name data is safe. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::hasDefaultGetPropertyNames): + * 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/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-09-11 Alexey Proskuryakov <ap@webkit.org> + + Reviewed by Geoff Garen. + + https://bugs.webkit.org/show_bug.cgi?id=29207 + Add checks for using WebCore JS context on secondary threads + + * runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + Added a new mainThreadOnly flag that WebCore would set. + + * runtime/Collector.cpp: (JSC::Heap::registerThread): JSC API methods always call this, + so this is a good place to check that the API isn't used form a wrong thread. + +2009-09-11 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + Compiling JavaScriptCore on sparc 64 with gcc fails. + + ThreadSafeShared uses the atomic __gnu_cxx::__exchange_and_add with an int, + however on sparc 64 the _Atomic_word argument is typedefed to long (8 bytes). + + The patch disables WTF_USE_LOCKFREE_THREADSAFESHARED in ThreadSafeShared to use + a mutex instead when compiling for sparc 64 with gcc. + + https://bugs.webkit.org/show_bug.cgi?id=29175 + + * wtf/Platform.h: + __sparc64__ is not defined on all OS. + Uses instead: __sparc__ && __arch64__ || __sparcv9 + * wtf/Threading.h: + +2009-09-11 Prasanth Ullattil <prasanth.ullattil@nokia.com> + + Reviewed by Simon Hausmann. + + Fix compile error on Windows7(64Bit) with latest SDK. + + Added the missing include file. + + * runtime/UString.cpp: + +2009-09-11 Joerg Bornemann <joerg.bornemann@trolltech.com> + + Reviewed by Simon Hausmann. + + Qt/Windows CE compile fix, include the executable allocator and + markstack implementation in the windows build. + + * JavaScriptCore.pri: + +2009-09-08 John Abd-El-Malek <jam@chromium.org> + + Reviewed by Dimitri Glazkov. + + Remove unneeded define for ActiveX. + https://bugs.webkit.org/show_bug.cgi?id=29054 + + * wtf/Platform.h: + +2009-09-10 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Sam Weinig. + + Update JavaScriptCore and WebKit's FeatureDefines.xcconfig so that they are in sync with WebCore as they need to be. + + * Configurations/FeatureDefines.xcconfig: + +2009-09-10 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Alexey Proskuryakov. + + Export WTF::tryFastMalloc used in WebSocketChannel. + https://bugs.webkit.org/show_bug.cgi?id=28038 + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-10 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Make StructureTransitionTable use an enum for the PtrAndFlags member + used for the single transition slot optimisation. + + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTable::StructureTransitionTable): + (JSC::StructureTransitionTable::usingSingleTransitionSlot): + (JSC::StructureTransitionTable::): + +2009-09-10 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Refactor StructureTransitionTable and Structure to unify handling of the single slot optimization + https://bugs.webkit.org/show_bug.cgi?id=29141 + + Make StructureTransitionTable encapsulate the single transition slot optimization. + + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::~Structure): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::removePropertyWithoutTransition): + (JSC::Structure::hasTransition): + * runtime/Structure.h: + (JSC::StructureTransitionTable::contains): + (JSC::StructureTransitionTable::get): + (JSC::StructureTransitionTable::hasTransition): + (JSC::StructureTransitionTable::reifySingleTransition): + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTable::StructureTransitionTable): + (JSC::StructureTransitionTable::~StructureTransitionTable): + (JSC::StructureTransitionTable::remove): + (JSC::StructureTransitionTable::add): + (JSC::StructureTransitionTable::table): + (JSC::StructureTransitionTable::singleTransition): + (JSC::StructureTransitionTable::usingSingleTransitionSlot): + (JSC::StructureTransitionTable::setSingleTransition): + (JSC::StructureTransitionTable::setTransitionTable): + (JSC::StructureTransitionTable::): + * wtf/PtrAndFlags.h: + (WTF::PtrAndFlags::PtrAndFlags): + +2009-09-10 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Implement fastDeleteSkippingDestructor for FastAllocBase and fastDeleteAllValues for HashSet + https://bugs.webkit.org/show_bug.cgi?id=25930 + + FastAllocBase has been extended with fastDeleteSkippingDestructor function which + releases memory without destructor call. fastDeleteAllValues has been implemented + similar as deleteAllValues but it uses fastDelete function to release memory. + + * wtf/FastAllocBase.h: + (WTF::fastDeleteSkippingDestructor): + * wtf/HashSet.h: + (WTF::fastDeleteAllValues): + +2009-09-10 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + ARM compiler does not understand GCC visibility attribute + https://bugs.webkit.org/show_bug.cgi?id=29079 + + * API/JSBase.h: Make the test more specific to hit only + the GCC compiler + +2009-09-10 Adam Barth <abarth@webkit.org> + + Unreviewed revert of the previous change. It broke the tests. + + * wtf/dtoa.cpp: + (WTF::dtoa): + +2009-09-10 Ben Laurie <benl@google.com> + + Reviewed by Adam Barth. + + <https://bugs.webkit.org/show_bug.cgi?id=26836> + + If dtoa was given a small buffer and the number was either infinite or + NaN, then the buffer would be overflowed. + + * wtf/dtoa.cpp: + +2009-09-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + Change reinterpret_cast to static_cast in r48212. + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-09-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + Remove WTF_PLATFORM_FORCE_PACK as it is no longer used + https://bugs.webkit.org/show_bug.cgi?id=29066 + + * wtf/Platform.h: + +2009-09-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Ariya Hidayat. + + Implement flushing the instruction cache for Symbian + https://bugs.webkit.org/show_bug.cgi?id=29075 + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): Call IMB_Range to flush + the instruction cache on Symbian + +2009-09-09 Kent Hansen <khansen@trolltech.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=29024 + Make JavaScriptCore compile on platforms with case-insensitive file systems and typeinfo.h in STL + + These platforms include Microsoft Visual Studio 2003, and Symbian with Metrowerks compiler. + + * JavaScriptCore.gypi: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSTypeInfo.h: Copied from JavaScriptCore/runtime/TypeInfo.h. + * runtime/Structure.h: + * runtime/TypeInfo.h: Removed. + +2009-09-08 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + JSON.stringify(Date) loses the milliseconds information + https://bugs.webkit.org/show_bug.cgi?id=29063 + + Make sure we include milliseconds in the output of toISOString. + + * runtime/DatePrototype.cpp: + (JSC::dateProtoFuncToISOString): + +2009-09-08 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix, generate derived sources earlier in order to make sure + they're found by the build system when generating the list of sources to build. + + * wscript: + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + Build fix when USE(LOCKFREE_THREADSAFESHARED) is not defined + https://bugs.webkit.org/show_bug.cgi?id=29011 + + * wtf/Threading.h: Use LOCKFREE_THREADSAFESHARED guard for + atomicIncrement and atomicDecrement + +2009-09-07 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control in Yarr's RegexInterpreter + https://bugs.webkit.org/show_bug.cgi?id=29025 + + Inherits RegexInterpreter classes from FastAllocBase (bug #20422), which has + been instantiated by 'new': + + class ByteDisjunction + -> instantiated in JavaScriptCore/yarr/RegexInterpreter.cpp:1462 + + struct BytecodePattern + -> instantiated in JavaScriptCore/yarr/RegexInterpreter.cpp:1279 + + * yarr/RegexInterpreter.h: + +2009-09-07 Drew Wilson <atwilson@google.com> + + Reverting r48121 to fix Windows build errors. + + * JavaScriptCore.exp: + +2009-09-07 Drew Wilson <atwilson@google.com> + + Reviewed by David Levin. + + Enable SHARED_WORKERS by default + https://bugs.webkit.org/show_bug.cgi?id=28959 + + * Configurations/FeatureDefines.xcconfig: + +2009-09-07 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Alexey Proskuryakov. + + Export WTF::tryFastMalloc used in WebSocketChannel. + https://bugs.webkit.org/show_bug.cgi?id=28038 + + * JavaScriptCore.exp: + +2009-09-04 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Fix windows export files + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-04 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + [[ToString]] conversion should use the actual toString function for String objects. + + Remove incorrect specialisations of toString conversions on StringObject. + + * JavaScriptCore.exp: + * runtime/StringObject.cpp: + * runtime/StringObject.h: + +2009-09-04 Steve Falkenburg <sfalken@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Add new export. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Add new export. + +2009-09-04 Steve Falkenburg <sfalken@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Remove unneeded export. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Remove unneeded export. + +2009-09-04 Darin Adler <darin@apple.com> + + Reviewed by Geoff Garen. + + DateInstance object collected on ARM JIT (JSValue: WTF_USE_JSVALUE32) + https://bugs.webkit.org/show_bug.cgi?id=28909 + + Part two. + + Make some improvements to garbage collection code: + + 1) Create a runtime assertion that catches any classes that + override markChildren but have the HasDefaultMark bit set. + 2) Remove checks of the mark bit outside the MarkStack::append + function; they are redundant. + 3) Improve the efficiency of the asObject and asArray functions + when called on JSCell* to avoid a round trip to JSValue. + 4) Make more callers use the checked asCell and asObject + casting functions rather than unchecked casts. + 5) Removed the JSCell::marked function and other GC-related + functions because these operations are no longer things that + code other than the core GC code needs to do directly. Fixed + callers that were calling them. + + * runtime/Collector.cpp: + (JSC::Heap::markConservatively): Removed unneeded call to MarkStack::drain. + (JSC::Heap::markProtectedObjects): Removed unneeded check of the mark + bit and call to MarkStack::drain. + (JSC::Heap::collect): Removed unneeded checks of the mark bit and also + changed call to SmallStrings::mark to call markChildren instead to match + the rest of the objects. + (JSC::typeName): Removed unneeded cast to JSObject*. + + * runtime/JSArray.h: + (JSC::asArray): Added an overload for JSCell* and changed the JSValue + version to call it. Removed some unneeded casts. + (JSC::JSArray::markChildrenDirect): Marked this function inline. It's in + a header, and if not marked inline this could lead to linking problems. + (JSC::MarkStack::markChildren): Added. This helper function is used by + the drain function to avoid repating code. Also added the code here to + check fro default mark violations in debug code. If a markChildren + function adds something to the mark stack, but the type info claimed + hasDefaultMark was true, then we will get an assertion now. Also fixed + the assertion about the mark bit to use the Heap function directly + because we don't have a JSCell::marked function any more. + (JSC::MarkStack::drain): Changed a local variable from "v" to "value", + and from "currentCell" to "cell". Changed to call markChildren in two + places instead of repeating a chain of if statements twice. Changed + code that reads and writes the mark bit to use Heap::isCellMarked and + Heap::markCell so we can eliminate the JSCell::marked and + JSCell::markCellDirect functions. + + * runtime/JSCell.h: Removed JSCell's markCellDirect and marked member + functions. Added a comment explaining that asCell should be deprecated + in favor of the JSValue asCell member function. + (JSC::MarkStack::append): Added the assertion that catches callers + that have set the HasDefaultMark bit incorrectly. Changed + code that reads and writes the mark bit to use Heap::isCellMarked and + Heap::markCell so we can eliminate the JSCell::marked and + JSCell::markCellDirect functions. Moved the overload of + MarkStack::append for JSValue here so it can call through to the cell + version. The old version had a copy of all the code instead, but that + repeated the conversion from JSValue to JSCell* and the check for + whether a value is a cell multiple times. + (JSC::Structure::markAggregate): Moved this function here to avoid + dependencies for Structure.h, since this calls MarkStack::append. + + * runtime/JSObject.cpp: + (JSC::JSObject::markChildren): Added code to clear + m_isCheckingForDefaultMarkViolation so the marking done by JSObject + doesn't trigger the assertion. + + * runtime/JSValue.h: Moved some stray includes that were outside the + header guard inside it. Not sure how that happened! Removed the + GC-related member functions markChildren, hasChildren, marked, and + markDirect. + + * runtime/JSWrapperObject.h: Made markChildren private. + (JSC::JSWrapperObject::createStructure): Added. Fixes a bug where the + HasDefaultMark bit was set. + + * runtime/MarkStack.h: Added m_isCheckingForDefaultMarkViolation and + initialized it to false. Moved the append function body from here to + JSCell.h. Added a declaration of a private markChildren function used + inside the drain function. + + * runtime/SmallStrings.cpp: + (JSC::SmallStrings::markChildren): Changed the name and style of this + function to match other functions. This allows us to share the normal + mark stack code path. + + * runtime/SmallStrings.h: Changed the name and interface of mark to + the more-normal markChildren style. + + * runtime/Structure.h: Moved the body of markAggregate into the + JSCell.h to avoid a circular dependency with JSCell.h. + +2009-09-04 Darin Adler <darin@apple.com> + + Reviewed by Geoff Garen. + + DateInstance object collected on ARM JIT (JSValue: WTF_USE_JSVALUE32) + https://bugs.webkit.org/show_bug.cgi?id=28909 + + Part one. + + Make some improvements to garbage collection code: + + 1) Fix the two classes that had the default mark bit set but + should not. + 2) Remove checks of the mark bit outside the MarkStack::append + function; they are redundant. + 3) Make more callers use the checked asCell and asObject + casting functions rather than unchecked casts. + 4) Removed some GC-related functions because these operations are + no longer things that code other than the core GC code needs + to do directly. Fixed callers that were calling them. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::markAggregate): Removed unneeded check of the mark + bit before calling MarkStack::append. + + * interpreter/Register.h: Removed unneeded marked and markChildren + functions. + + * jit/JITStubs.cpp: + (op_eq): Removed unneeded assertions, instead using checked casting + functions such as asObject. + + * runtime/ArgList.h: Added now-needed forward declaration of MarkStack. + + * runtime/GetterSetter.cpp: + (JSC::GetterSetter::markChildren): Remmoved unneeded check of the mark bit. + + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): Added. Fixes a bug where the + HasDefaultMark bit was set. + + * runtime/JSCell.cpp: + (JSC::JSCell::getObject): Use asObject to avoid a direct static_cast. + + * runtime/JSObject.h: + (JSC::asObject): Added an overload for JSCell* and changed the JSValue + version to call it. + (JSC::JSValue::get): Use asObject to avoid a direct static_cast. + + * runtime/JSWrapperObject.h: Made markChildren private. + (JSC::JSWrapperObject::createStructure): Added. Fixes a bug where the + HasDefaultMark bit was set. Later we may want to optimize this for + wrapper types that never have cells in their internal values, but there + is no measured performance regression in SunSpider or V8 doing this + all the time. + + * runtime/MarkStack.cpp: Tweaked formatting. + +2009-09-04 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Switch USE_ defines over to the compiler so that they can be + checked by files not including config.h (like WebCorePrefix.h). + + * wtf/Platform.h: + +2009-09-03 Yong Li <yong.li@torchmobile.com> + + Reviewed by David Levin. + + Remove unnecessary dependency on unistd.h + https://bugs.webkit.org/show_bug.cgi?id=28962 + + * runtime/Completion.cpp: + +2009-09-03 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Eric Seidel. + + Add strnstr for Linux and Windows in StringExtras.h + https://bugs.webkit.org/show_bug.cgi?id=28901 + + * wtf/StringExtras.h: + (strnstr): + +2009-09-03 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's HashEntry class + https://bugs.webkit.org/show_bug.cgi?id=27830 + + Inherits HashEntry class from FastAllocBase because it has been + instantiated by 'new' JavaScriptCore/runtime/Lookup.cpp:32. + + * runtime/Lookup.h: + +2009-09-02 Gavin Barraclough <barraclough@apple.com> + + Should crash if JIT code buffer allocation fails. + + https://bugs.webkit.org/show_bug.cgi?id=28926 + <rdar://problem/7031922> + + * jit/ExecutableAllocatorPosix.cpp: + (JSC::ExecutablePool::systemAlloc): + * jit/ExecutableAllocatorWin.cpp: + (JSC::ExecutablePool::systemAlloc): + +2009-09-02 Kevin Ollivier <kevino@theolliviers.com> + + waf build fixes for Windows/MSVC. + + * wscript: + +2009-09-02 Kevin Ollivier <kevino@theolliviers.com> + + Build fix for building on Windows. + + * wtf/ThreadingPthreads.cpp: + +2009-09-02 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Eric Seidel. + + Use fastMalloc when neither MMAP nor VIRTUALALLOC are enabled + + RegisterFile constructor currently throws #error when both + MMAP and VIRTUALALLOC conditions fail. + On any platform that does not provide these features + (for instance, Symbian), + the fallback should be regular malloc (or fastMalloc). + It is functionally equivalent in this case, even though it may + have certain drawbacks such as lack of dynamic pre-allocation. + + * interpreter/RegisterFile.cpp: + (JSC::RegisterFile::~RegisterFile): + * interpreter/RegisterFile.h: + (JSC::RegisterFile::RegisterFile): + +2009-08-31 Robert Agoston <Agoston.Robert@stud.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Fixed typo. + https://bugs.webkit.org/show_bug.cgi?id=28691 + + * parser/Parser.h: + (JSC::Parser::parse): + +2009-08-27 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + JSON Stringifier does not follow ES5 spec for handling of Number, String and Boolean objects + https://bugs.webkit.org/show_bug.cgi?id=28797 + + Fixed unwrapBoxedPrimitive to do the right thing, which necessitated a couple of new exception + checks, and corrected the logic in gap to correctly convert Number and String objects. + + * runtime/JSONObject.cpp: + (JSC::unwrapBoxedPrimitive): + (JSC::gap): + (JSC::Stringifier::Stringifier): + (JSC::Stringifier::appendStringifiedValue): + +2009-08-27 Oliver Hunt <oliver@apple.com> + + Reviewed by Adam Roben. + + JSON.stringify replacer array does not accept values that are not string primitives. + https://bugs.webkit.org/show_bug.cgi?id=28788 + + Update the JSON stringifier to initialise its replacer array according to the most + recent version of the spec. + + * runtime/Identifier.h: + (JSC::Identifier::from): + * runtime/JSONObject.cpp: + (JSC::Stringifier::Stringifier): + +2009-08-27 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=28753 + <rdar://problem/7173448> Excessive number of threads (and a crash) + + * wtf/Threading.h: (WTF::atomicIncrement): Changed atomicIncrement to match decrement + and return the new value. Also added using directives for these functions, to match + te rest of WTF. + +2009-08-27 Brent Fulgham <bfulgham@webkit.org> + + Reviewed by Adam Roben. + + Link the testapi against CFLite when building the WinCairo port. + + * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add new Release_CFLite + target. Update all targets to inherit from either the + JavaScriptCF.vsprops (Apple target) or the JavaScriptCFLite.vsprops + file (WinCairo target). + * JavaScriptCore.vcproj/testapi/testapiCommon.vsprops: Remove + input file CoreFoundation.lib. This is provided by either the + JavaScriptCF.vsprops or JavaScriptCFLite.vsprops file. + +2009-08-27 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Geoff Garen. + + Fix Windows-specific crash due to missing memory clearing call. + + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): + +2009-08-27 Brent Fulgham <bfulgham@webkit.org> + + Build fix: JavaScriptCore_debug.def missing some exports. Apple + Windows build does not use this file, so it was not noticed previously. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-27 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + x86-64 GTK broken due to code offsets changing, pointers sometimes packed into immediates. + https://bugs.webkit.org/show_bug.cgi?id=28317 + + Missed one, fix part II. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::move): + * assembler/X86Assembler.h: + (JSC::CAN_SIGN_EXTEND_8_32): + +2009-08-27 Oliver Hunt <oliver@apple.com> + + Reviewed by Adam Roben. + + JSON.stringify replacer array does not accept values that are not string primitives. + https://bugs.webkit.org/show_bug.cgi?id=28788 + + Update the JSON stringifier to initialise its replacer array according to the most + recent version of the spec. + + * runtime/Identifier.h: + (JSC::Identifier::from): + * runtime/JSONObject.cpp: + (JSC::Stringifier::Stringifier): + +2009-08-27 Oliver Hunt <oliver@apple.com> + + Reviewed by Alexey Proskuryakov. + + JSON parser accepts trailing comma in array literals + https://bugs.webkit.org/show_bug.cgi?id=28779 + + Update parser to correctly fail if there's a trailing comma. + + * runtime/LiteralParser.cpp: + (JSC::LiteralParser::parse): + +2009-08-26 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + 'this' in JSON.parse reviver is the global object + https://bugs.webkit.org/show_bug.cgi?id=28752 + + This is a technically simple change, we merely update the code for calling + the reviver function to pass the correct this object. Doing so however + exposes the holder to arbitrary mutation by the reviver function so it is + necessary for us to now guard all property accesses against the possibility + of failure. + + * runtime/JSArray.h: + JSON needs to delete a property from the array, so we friend its + Walker class so that we can make a non-virtual call to the arrays + delete and getOwnPropertySlot methods. + * runtime/JSONObject.cpp: + (JSC::Walker::callReviver): + We need to pass the correct this object + (JSC::Walker::walk): + Update calls to callReviver, and update property logic logic + to correctly handle the holder being mutated by the reviver + function. + +2009-08-26 Alice Liu <alice.liu@apple.com> + + Windows build fix: added some exported symbols + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-26 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Removed some exported symbols that no longer exist. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-26 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Olliejver Hunt. + + x86-64 GTK broken due to code offsets changing, pointers sometimes packed into immediates. + https://bugs.webkit.org/show_bug.cgi?id=28317 + + We rely on a slightly OS X specific behaviour, that x86-64 applications have a 4Gb zero page, + so pointers are never representable as a 32-bit integer, and always have to be represented by + a separate immediate load instruction, rather than within the immediate field of an arithmetic + or memory operation. + + We explicitly check for a couple of cases where a value might be representable in 32-bit, but + these probably never kick in on Mac OS, and only kick in to hose GTK. Deleting these does not + show a performance degradation on SunSpider. Remove. + + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::storePtr): + (JSC::MacroAssemblerX86_64::branchPtr): + +2009-08-26 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + A bit of Collector refatoring. + + SunSpider says no change. v8 says 1.003x faster (1.02x faster on splay). + + * JavaScriptCore.exp: + + * runtime/JSCell.cpp: + (JSC::JSCell::toPrimitive): + (JSC::JSCell::getPrimitiveNumber): + (JSC::JSCell::toBoolean): + (JSC::JSCell::toNumber): + (JSC::JSCell::toString): + (JSC::JSCell::toObject): Removed pure virtual functions from + JSCell, so the collector can construct one. This allowed + me to remove a bunch of ASSERT_NOT_REACHED throughout the + code, too. + + * runtime/JSCell.h: + (JSC::JSCell::JSCell): ditto + (JSC::Heap::heap): Inlined this function because it's trivial. + + * JavaScriptCore.exp: + + * runtime/Collector.cpp: + (JSC::Heap::destroy): + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlock): + (JSC::Heap::freeBlocks): Renamed freeHeap to freeBlocks, since + it doesn't actually free the Heap object. + (JSC::Heap::heapAllocate): + (JSC::Heap::sweep): + * runtime/Collector.h: Refactored block allocation and destruction + into helper functions. + + * runtime/GetterSetter.cpp: + * runtime/JSAPIValueWrapper.cpp: + * runtime/JSPropertyNameIterator.cpp: Removed dummy implementations + of pure virtual functions. (See above.) + +=== End re-roll-in of r47738:47740 with Windows crash fixed === + +2009-08-26 Geoffrey Garen <ggaren@apple.com> + + Build fix: start out with a 32-bit value to avoid a shortening warning. + + * runtime/Collector.cpp: + (JSC::Heap::sweep): + +2009-08-24 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Substantially reduced VM thrash in the GC heap. + + 1.08x faster on v8 (1.60x faster on v8-splay). + + 1.40x faster on bench-alloc-nonretained. + + 1.90x faster on bench-alloc-retained. + + SunSpider says no change. + + * runtime/Collector.cpp: + (JSC::Heap::heapAllocate): Fixed a long-standing bug: update a few local + variables unconditionally after calling collect(), since they may be used + even if we don't "goto scan". (In the bug I saw, usedBlocks got out of + sync with heap.usedBlocks). + (JSC::Heap::sweep): Keep enough free heap space to accomodate + the number of objects we'll allocate before the next GC, plus 25%, for + good measure. + * runtime/Collector.h: Bumped the block size to 256k. This seems to give + the best cache performance, and it prevents us from initiating lots of + VM traffic to recover very small chunks of memory. + +=== Begin re-roll-in of r47738:47740 with Windows crash fixed === + +2009-08-25 Drew Wilson <atwilson@google.com> + + Reviewed by David Levin. + + postMessage() spec now supports sending arrays of ports + https://bugs.webkit.org/show_bug.cgi?id=26902 + + Added OwnPtr to VectorTraits so we can store OwnPtrs in Vectors. + + * wtf/VectorTraits.h: + +2009-08-26 Xan Lopez <xlopez@igalia.com> + + Rubber-stamped by Gustavo Noronha. + + Remove duplicated files from file list. + + * GNUmakefile.am: + +2009-08-26 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + More export fixes. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-26 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Hopefully fix all the exports from JSC on windows + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-26 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fixes). + + Forgot I added files to JavaScriptCore. + + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pri: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCoreSources.bkl: + +2009-08-25 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + [ES5] Implement getOwnPropertyDescriptor + https://bugs.webkit.org/show_bug.cgi?id=28724 + + Implement the core runtime support for getOwnPropertyDescriptor. + This adds a virtual getOwnPropertyDescriptor method to every class + that implements getOwnPropertySlot that shadows the behaviour of + getOwnPropertySlot. The alternative would be to make getOwnPropertySlot + (or PropertySlots in general) provide property attribute information, + but quick testing showed this to be a regression. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertyDescriptor): + * runtime/Arguments.h: + * runtime/ArrayPrototype.cpp: + (JSC::ArrayPrototype::getOwnPropertyDescriptor): + * runtime/ArrayPrototype.h: + * runtime/CommonIdentifiers.h: + * runtime/DatePrototype.cpp: + (JSC::DatePrototype::getOwnPropertyDescriptor): + * runtime/DatePrototype.h: + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertyDescriptor): + * runtime/JSArray.h: + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::getOwnPropertyDescriptor): + * runtime/JSByteArray.h: + * runtime/JSFunction.cpp: + (JSC::JSFunction::getOwnPropertyDescriptor): + * runtime/JSFunction.h: + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::getOwnPropertyDescriptor): + * runtime/JSNotAnObject.cpp: + (JSC::JSNotAnObject::getOwnPropertyDescriptor): + * runtime/JSNotAnObject.h: + * runtime/JSONObject.cpp: + (JSC::JSONObject::getOwnPropertySlot): + (JSC::JSONObject::getOwnPropertyDescriptor): + * runtime/JSONObject.h: + * runtime/JSObject.cpp: + (JSC::JSObject::getOwnPropertyDescriptor): + (JSC::JSObject::getPropertyDescriptor): + * runtime/JSObject.h: + * runtime/JSString.cpp: + (JSC::JSString::getStringPropertyDescriptor): + (JSC::JSString::getOwnPropertyDescriptor): + * runtime/JSString.h: + * runtime/JSVariableObject.cpp: + (JSC::JSVariableObject::symbolTableGet): + * runtime/JSVariableObject.h: + * runtime/Lookup.h: + (JSC::getStaticPropertyDescriptor): + (JSC::getStaticFunctionDescriptor): + (JSC::getStaticValueDescriptor): + Add property descriptor equivalents of the lookup + table access functions + + * runtime/MathObject.cpp: + (JSC::MathObject::getOwnPropertySlot): + (JSC::MathObject::getOwnPropertyDescriptor): + * runtime/MathObject.h: + * runtime/NumberConstructor.cpp: + (JSC::NumberConstructor::getOwnPropertyDescriptor): + * runtime/NumberConstructor.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorGetOwnPropertyDescriptor): + * runtime/PropertyDescriptor.cpp: Added. + (JSC::PropertyDescriptor::writable): + (JSC::PropertyDescriptor::enumerable): + (JSC::PropertyDescriptor::configurable): + (JSC::PropertyDescriptor::hasAccessors): + (JSC::PropertyDescriptor::setUndefined): + (JSC::PropertyDescriptor::getter): + (JSC::PropertyDescriptor::setter): + (JSC::PropertyDescriptor::setDescriptor): + (JSC::PropertyDescriptor::setAccessorDescriptor): + * runtime/PropertyDescriptor.h: Added. + (JSC::PropertyDescriptor::PropertyDescriptor): + (JSC::PropertyDescriptor::attributes): + (JSC::PropertyDescriptor::isValid): + (JSC::PropertyDescriptor::value): + * runtime/RegExpConstructor.cpp: + (JSC::RegExpConstructor::getOwnPropertyDescriptor): + * runtime/RegExpConstructor.h: + * runtime/RegExpMatchesArray.h: + (JSC::RegExpMatchesArray::getOwnPropertyDescriptor): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::getOwnPropertyDescriptor): + * runtime/RegExpObject.h: + * runtime/StringObject.cpp: + (JSC::StringObject::getOwnPropertyDescriptor): + * runtime/StringObject.h: + * runtime/StringPrototype.cpp: + (JSC::StringPrototype::getOwnPropertyDescriptor): + * runtime/StringPrototype.h: + +2009-08-24 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Darin Adler. + + How many copies of the parameters do you need? + https://bugs.webkit.org/show_bug.cgi?id=28701 + + The function parameters in JSC get copied a lot - and unnecessarily so. + + Originally this happened due to duplicating FunctionBodyNodes on recompilation, + though the problem has been exacerbated by copying the parameters from the + original function body onto the executable, then back onto the real body that + will be generated (this happens on every function). And this is all made worse + since the data structures in question are a little ugly - C style arrays of C++ + objects containing ref counts, so they need a full copy-construct (rather than + a simple memcpy). + + This can all be greatly simplified by just punting the parameters off into + their own ref-counted object, and forgoing all the copying. + + ~no performance change, possible slight progression. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::makeFunction): + * parser/Nodes.cpp: + (JSC::FunctionParameters::FunctionParameters): + (JSC::FunctionBodyNode::FunctionBodyNode): + (JSC::FunctionBodyNode::finishParsing): + * parser/Nodes.h: + (JSC::FunctionBodyNode::parameters): + (JSC::FunctionBodyNode::parameterCount): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::~FunctionExecutable): + (JSC::FunctionExecutable::compile): + (JSC::FunctionExecutable::reparseExceptionInfo): + (JSC::FunctionExecutable::fromGlobalCode): + (JSC::FunctionExecutable::paramString): + * runtime/Executable.h: + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::FunctionExecutable::parameterCount): + +2009-08-25 Brent Fulgham <bfulgham@webkit.org> + + Reviewed by NOBODY (Buildfix). + + * JavaScriptCore.vcproj/jsc/jsc.vcproj: Add Debug_CFLite target + that inherits from the debug_wincairo property sheet and therefore + links to the proper debug library. + * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add Debug_CFLite target + that inherits from the debug_wincairo property sheet and therefore + links to the proper debug library. + +2009-08-25 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Export tryFastMalloc for Canvas3D work + https://bugs.webkit.org/show_bug.cgi?id=28018 + + * JavaScriptCore.exp: + +2009-08-25 David Levin <levin@chromium.org> + + Reviewed by Adam Roben. + + PLATFORM(CFNETWORK) should be USE(CFNETWORK). + https://bugs.webkit.org/show_bug.cgi?id=28713 + + * wtf/Platform.h: Added a #define to catch this issue in the + future. The define would generate an error on gcc without the + space in the expansion, but Visual C++ needs the space to cause an error. + +2009-08-24 Brent Fulgham <bfulgham@webkit.org> + + Reviewed by Steve Falkenburg. + + Revise CFLite Debug build to emit DLL's with _debug label. + https://bugs.webkit.org/show_bug.cgi?id=28695. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Modify + Cairo debug build to inherit from new debug_cairo property sheet. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCFLite.vsprops: + Modify to look for debug CFLite when in debug build. + +2009-08-24 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Adler & Darin Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=28691 + Do not retain ScopeNodes outside of parsing + + There is now no need for these to exist outside of parsing - their use in the runtime is replaced by Executable types. + + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::emitNewFunction): + (JSC::BytecodeGenerator::emitNewFunctionExpression): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::makeFunction): + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + (JSC::evaluateInGlobalCallFrame): + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::evaluate): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + (JSC::Interpreter::prepareForRepeatCall): + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * parser/Nodes.cpp: + (JSC::ScopeNodeData::ScopeNodeData): + (JSC::ProgramNode::create): + (JSC::EvalNode::create): + (JSC::FunctionBodyNode::create): + * parser/Nodes.h: + (JSC::ScopeNode::adoptData): + (JSC::FunctionBodyNode::parameterCount): + * parser/Parser.cpp: + * parser/Parser.h: + (JSC::Parser::arena): + (JSC::Parser::Parser): + (JSC::Parser::parse): + * runtime/ArrayPrototype.cpp: + (JSC::isNumericCompareFunction): + (JSC::arrayProtoFuncSort): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::~FunctionExecutable): + (JSC::EvalExecutable::compile): + (JSC::ProgramExecutable::checkSyntax): + (JSC::ProgramExecutable::compile): + (JSC::FunctionExecutable::compile): + (JSC::EvalExecutable::generateJITCode): + (JSC::ProgramExecutable::generateJITCode): + (JSC::FunctionExecutable::generateJITCode): + (JSC::FunctionExecutable::reparseExceptionInfo): + (JSC::EvalExecutable::reparseExceptionInfo): + (JSC::FunctionExecutable::recompile): + (JSC::FunctionExecutable::fromGlobalCode): + (JSC::FunctionExecutable::copyParameters): + (JSC::FunctionExecutable::paramString): + * runtime/Executable.h: + (JSC::ScriptExecutable::ScriptExecutable): + (JSC::ScriptExecutable::sourceID): + (JSC::ScriptExecutable::sourceURL): + (JSC::ScriptExecutable::lineNo): + (JSC::ScriptExecutable::lastLine): + (JSC::ScriptExecutable::usesEval): + (JSC::ScriptExecutable::usesArguments): + (JSC::ScriptExecutable::needsActivation): + (JSC::ScriptExecutable::recordParse): + (JSC::EvalExecutable::bytecode): + (JSC::EvalExecutable::jitCode): + (JSC::ProgramExecutable::bytecode): + (JSC::ProgramExecutable::reparseExceptionInfo): + (JSC::ProgramExecutable::jitCode): + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::FunctionExecutable::make): + (JSC::FunctionExecutable::bytecode): + (JSC::FunctionExecutable::isGenerated): + (JSC::FunctionExecutable::name): + (JSC::FunctionExecutable::parameterCount): + (JSC::FunctionExecutable::jitCode): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunction): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::numericCompareFunction): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + +2009-08-24 Darin Adler <darin@apple.com> + + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::put): Landed revised version I had tested but forgot + to land. Leave out the branch, since we don't need one. + +2009-08-24 Darin Adler <darin@apple.com> + + Reviewed by Geoff Garen. + + Array index miss case creates a string every time + https://bugs.webkit.org/show_bug.cgi?id=28664 + + SunSpider test results I saw: + + 0.5% faster overall + 1% faster on crypto-aes + 20% faster on crypto-md5 + 13% faster on crypto-sha1 + + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::ObjectPrototype): Initialize m_hasNoPropertiesWithUInt32Names + to true. + (JSC::ObjectPrototype::put): Clearly m_hasNoPropertiesWithUInt32Names if the new + property has a name that is the string form of a UInt32. + (JSC::ObjectPrototype::getOwnPropertySlot): Don't call JSObject::getOwnPropertySlot + if m_hasNoPropertiesWithUInt32Names is true, and it is highly likely to be true. + + * runtime/ObjectPrototype.h: Added declarations for the above. + +2009-08-24 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed. Fix a typo in my distcheck build fix. + + * GNUmakefile.am: + +2009-08-23 Gustavo Noronha Silva <gns@gnome.org> + + Unreviewed build fix for make distcheck. + + * GNUmakefile.am: Added files required for the build. + +2009-08-22 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Mark Rowe. + + REGRESSION(r47639-r47660): Webkit crashes on launch on PowerPC + https://bugs.webkit.org/show_bug.cgi?id=28655 + + * runtime/JSFunction.cpp: + (JSC::JSFunction::JSFunction): Initialize properly with a VPtrHackExecutable. + * wtf/Platform.h: + +2009-08-22 Darin Adler <darin@apple.com> + + Fix storage leak from syntax tree arena allocation patch. + + * parser/Nodes.h: CommaNode needs to inherit from ParserArenaDeletable + because it has a vector. + +2009-08-21 Darin Adler <darin@apple.com> + + Fix Qt build. + + * parser/Nodes.cpp: + (JSC::ScopeNodeData::ScopeNodeData): Made non-inline again. + This is used outside Nodes.cpp so can't be inline unless + it is in the header. + +2009-08-21 Darin Adler <darin@apple.com> + + Two loose ends from the last commit. + + * JavaScriptCore.xcodeproj/project.pbxproj: Made ParserArena.h + and create_hash_table project-internal instead of "private". + * runtime/Executable.h: Removed accidentally-added constructor. + +2009-08-21 Darin Adler <darin@apple.com> + + Reviewed by Gavin Barraclough. + + Syntax tree nodes should use arena allocation + https://bugs.webkit.org/show_bug.cgi?id=25674 + + Use an actual arena now. 0.6% speedup on SunSpider. + + New and improved with 100% less leaking of the universe. + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + Removed all exports involving the class FunctionBodyNode, which no + longer needs to be used outside JavaScriptCore. + + * JavaScriptCore.xcodeproj/project.pbxproj: Made Nodes.h and + Executable.h project-internal instead of "private". + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Updated since VarStack + contains const Identifier* now. + + * parser/Grammar.y: Made identifiers from the lexer be const + Identifier* and updated since VarStack contains const Identifier* now. + + * parser/Lexer.cpp: + (JSC::Lexer::setCode): Pass in ParserArena, used for identifiers. + (JSC::Lexer::makeIdentifier): Changed return type to const Identifier* + and changed to call ParserArena. + (JSC::Lexer::clear): Removed the code to manage m_identifiers and + added code to set m_arena to 0. + * parser/Lexer.h: Updated for changes above. + + * parser/NodeConstructors.h: + (JSC::ParserArenaFreeable::operator new): Added. Calls allocateFreeable + on the arena. + (JSC::ParserArenaDeletable::operator new): Changed to call the + allocateDeletable function on the arena instead of deleteWithArena. + (JSC::PropertyNode::PropertyNode): Added new constructor that makes + numeric identifiers. Some day we might want to optimize this for + integers so it doesn't create a string for each one. + (JSC::ContinueNode::ContinueNode): Initialize m_ident to nullIdentifier + since it's now a const Identifier& so it can't be left uninitialized. + (JSC::BreakNode::BreakNode): Ditto. + (JSC::CaseClauseNode::CaseClauseNode): Updated to use SourceElements* + to keep track of the statements rather than a separate statement vector. + (JSC::BlockNode::BlockNode): Ditto. + (JSC::ForInNode::ForInNode): Initialize m_ident to nullIdentifier. + + * parser/Nodes.cpp: Moved the comment explaining emitBytecode in here. + It seemed strangely out of place in the header. + (JSC::ThrowableExpressionData::emitThrowError): Added an overload for + UString as well as Identifier. + (JSC::SourceElements::singleStatement): Added. + (JSC::SourceElements::lastStatement): Added. + (JSC::RegExpNode::emitBytecode): Changed the throwError code to use + the substitution mechanism instead of doing a string append. + (JSC::SourceElements::emitBytecode): Added. Replaces the old + statementListEmitCode function, since we now keep the SourceElements + objects around. + (JSC::BlockNode::lastStatement): Added. + (JSC::BlockNode::emitBytecode): Changed to use emitBytecode instead of + statementListEmitCode. + (JSC::CaseClauseNode::emitBytecode): Added. + (JSC::CaseBlockNode::emitBytecodeForBlock): Changed to use emitBytecode + instead of statementListEmitCode. + (JSC::ScopeNodeData::ScopeNodeData): Changed to store the + SourceElements* instead of using releaseContentsIntoVector. + (JSC::ScopeNode::emitStatementsBytecode): Added. + (JSC::ScopeNode::singleStatement): Added. + (JSC::ProgramNode::emitBytecode): Call emitStatementsBytecode instead + of statementListEmitCode. + (JSC::EvalNode::emitBytecode): Ditto. + (JSC::FunctionBodyNode::emitBytecode): Call emitStatementsBytecode + insetad of statementListEmitCode and check for the return node using + the new functions. + + * parser/Nodes.h: Changed VarStack to store const Identifier* instead + of Identifier and rely on the arena to control lifetime. Added a new + ParserArenaFreeable class. Made ParserArenaDeletable inherit from + FastAllocBase instead of having its own operator new. Base the Node + class on ParserArenaFreeable. Changed the various Node classes + to use const Identifier& instead of Identifier to avoid the need to + call their destructors and allow them to function as "freeable" in the + arena. Removed extraneous JSC_FAST_CALL on definitions of inline functions. + Changed ElementNode, PropertyNode, ArgumentsNode, ParameterNode, + CaseClauseNode, ClauseListNode, and CaseBlockNode to use ParserArenaFreeable + as a base class since they do not descend from Node. Eliminated the + StatementVector type and instead have various classes use SourceElements* + instead of StatementVector. This prevents those classes from having to + use ParserArenaDeletable to make sure the vector destructor is called. + + * parser/Parser.cpp: + (JSC::Parser::parse): Pass the arena to the lexer. + + * parser/Parser.h: Added an include of ParserArena.h, which is no longer + included by Nodes.h. + (JSC::Parser::parseFunctionFromGlobalCode): Changed to use the + singleStatement function, since there is no longer any children function. + Removed some unneeded use of RefPtr. + + * parser/ParserArena.cpp: + (JSC::ParserArena::ParserArena): Added. Initializes the new members, + m_freeableMemory, m_freeablePoolEnd, and m_identifiers. + (JSC::ParserArena::freeablePool): Added. Computes the pool pointer, + since we store only the current pointer and the end of pool pointer. + (JSC::ParserArena::deallocateObjects): Added. Contains the common + memory-deallocation logic used by both the destructor and the + reset function. + (JSC::ParserArena::~ParserArena): Changed to call deallocateObjects. + (JSC::ParserArena::reset): Ditto. Also added code to zero out the + new structures, and switched to use clear() instead of shrink(0) since + we don't really reuse arenas. + (JSC::ParserArena::makeNumericIdentifier): Added. + (JSC::ParserArena::allocateFreeablePool): Added. Used when the pool + is empty. + (JSC::ParserArena::isEmpty): Added. No longer inline, which is fine + since this is used only for assertions at the moment. + (JSC::ParserArena::derefWithArena): Make non-inline. + + * parser/ParserArena.h: Added an actual arena of "freeable" objects, + ones that don't need destructors to be called. Also added a separate + IdentifierArena object, a segmented vector of identifiers that used + to be in the Lexer. + + * runtime/Executable.h: Moved the definition of the + FunctionExecutable::make function here. It can't go in JSFunction.h + since that header has to be used outside JavaScriptCore and so can't + include this, which includes Nodes.h. The function could be moved + elswhere if we don't want to include JSFunction.h in this header, but + for now this seems to be the best place. + + * runtime/JSFunction.h: Removed the include of Executable.h and + definition of the FunctionExecutable::make function. + + * wtf/FastMalloc.cpp: Fixed an incorrect comment. + +2009-08-21 Mark Rowe <mrowe@apple.com> + + Fix the non-JIT build. + + * runtime/Executable.cpp: + * runtime/Executable.h: + +2009-08-21 Gavin Barraclough <barraclough@apple.com> + + Speculative QuickTime build fix. + + * runtime/JSArray.cpp: + +2009-08-21 Gavin Barraclough <barraclough@apple.com> + + Speculative QT build fix. + + * runtime/StringPrototype.cpp: + +2009-08-21 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Restructure Executable types so that host functions do not hold a FunctionExecutable. + https://bugs.webkit.org/show_bug.cgi?id=28621 + + All JSFunction objects have a pointer to an Executable*. This is currently always a + FunctionExecutable, however this has a couple of drawbacks. Host functions do not + store a range of information that the FunctionExecutable provides (source, name, + CodeBlock & information presently held on the FunctionBodyNode). + + [ * nearly all... see below! ] + + Instead, make JSFunctions hold a pointer to an ExecutableBase, move fields specific + to JS sourced executable types (source, node) into a new subclass (ScriptExecutable), + and create a new NativeExecutable type. We now provide a new method in JSFunction + to access & downcast to FunctionExecutable, but in doing so we can make an early + check (with an ASSERT) to ensure that the Executable read from a function will only + be treated as a FunctionExecutable (and thus the JS sepcific fields will only be + accessed) if the JSFunction is not a host function. + + There is one JSFunction that currently does not have an Executable, which is the + object created to allow us to read out the vtable pointer. By making this change + we can also add a new Executable type fror this object (VPtrHackExecutable). + Since this means that really all JSFunctions have an Executable we no longer have + to null-check m_executable before us it - particularly in isHostFunction(). + + This patch removes CacheableEvalExecutable, since all subclasses of ExecutableBase + can now be ref-counted - since both JSFunction holds (and ref-counts) an ExecutableBase + that might be a FunctionExecutable or a NativeExecutable. This does now mean that all + ProgramExecutables and EvalExecutables (unnecessarily) provide an interface to be + ref-counted, however this seems less-bad than host functions unnecessarily providing + interface to access non-host specific information. + + The class hierarcy has changed from this: + + - ExecutableBase + - ProgramExecutable + - EvalExecutable + - CacheableEvalExecutable (also RefCounted by multiple-inheritance) + - FunctionExecutable (also RefCounted by multiple-inheritance, 'special' FunctionExecutable also used for host functions) + + To this: + + - RefCounted + - ExecutableBase + - NativeExecutable + - VPtrHackExecutable + - ScriptExecutable + - ProgramExecutable + - EvalExecutable + - FunctionExecutable + + This patch speeds up sunspidey by a couple of ms (presumably due to the changes to isHostFunction()). + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::ownerExecutable): + (JSC::GlobalCodeBlock::GlobalCodeBlock): + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + * interpreter/CachedCall.h: + (JSC::CachedCall::CachedCall): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::callEval): + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * profiler/Profiler.cpp: + (JSC::createCallIdentifierFromFunctionImp): + * runtime/Arguments.h: + (JSC::Arguments::getArgumentsData): + (JSC::Arguments::Arguments): + * runtime/Executable.cpp: + (JSC::NativeExecutable::~NativeExecutable): + (JSC::VPtrHackExecutable::~VPtrHackExecutable): + * runtime/Executable.h: + (JSC::ExecutableBase::ExecutableBase): + (JSC::ExecutableBase::~ExecutableBase): + (JSC::ExecutableBase::isHostFunction): + (JSC::NativeExecutable::NativeExecutable): + (JSC::VPtrHackExecutable::VPtrHackExecutable): + (JSC::ScriptExecutable::ScriptExecutable): + (JSC::ScriptExecutable::source): + (JSC::ScriptExecutable::sourceID): + (JSC::ScriptExecutable::sourceURL): + (JSC::ScriptExecutable::lineNo): + (JSC::ScriptExecutable::lastLine): + (JSC::ScriptExecutable::usesEval): + (JSC::ScriptExecutable::usesArguments): + (JSC::ScriptExecutable::needsActivation): + (JSC::EvalExecutable::EvalExecutable): + (JSC::EvalExecutable::create): + (JSC::ProgramExecutable::ProgramExecutable): + (JSC::FunctionExecutable::FunctionExecutable): + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncToString): + * runtime/JSFunction.cpp: + (JSC::JSFunction::JSFunction): + (JSC::JSFunction::~JSFunction): + (JSC::JSFunction::markChildren): + (JSC::JSFunction::getCallData): + (JSC::JSFunction::call): + (JSC::JSFunction::lengthGetter): + (JSC::JSFunction::getConstructData): + (JSC::JSFunction::construct): + * runtime/JSFunction.h: + (JSC::JSFunction::executable): + (JSC::JSFunction::jsExecutable): + (JSC::JSFunction::isHostFunction): + +2009-08-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Browser hangs on opening Web Inspector. + https://bugs.webkit.org/show_bug.cgi?id=28438 + + Code generation needs to be able to walk the entire scopechain in some + cases, however the symbol table used by activations was a member of the + codeblock. Following recompilation this may no longer exist, leading + to a crash or hang on lookup. + + We fix this by introducing a refcounted SymbolTable subclass, SharedSymbolTable, + for the CodeBlocks used by function code. This allows activations to + maintain ownership of a copy of the symbol table even after recompilation so + they can continue to work. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::symbolTable): + (JSC::CodeBlock::sharedSymbolTable): + (JSC::GlobalCodeBlock::GlobalCodeBlock): + (JSC::FunctionCodeBlock::FunctionCodeBlock): + (JSC::FunctionCodeBlock::~FunctionCodeBlock): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::retrieveArguments): + * runtime/Executable.cpp: + (JSC::EvalExecutable::generateBytecode): + (JSC::FunctionExecutable::generateBytecode): + (JSC::FunctionExecutable::reparseExceptionInfo): + (JSC::EvalExecutable::reparseExceptionInfo): + * runtime/JSActivation.h: + (JSC::JSActivation::JSActivationData::JSActivationData): + (JSC::JSActivation::JSActivationData::~JSActivationData): + * runtime/SymbolTable.h: + +2009-08-20 Xan Lopez <xlopez@igalia.com> + + Add new file to GTK+ build. + + * GNUmakefile.am: + +2009-08-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + Added a number => string cache. + + 1.07x faster on v8 (1.7x faster on v8-splay). + 1.004x faster on SunSpider. + + * runtime/JSCell.h: Moved JSValue::toString to JSString.h. + * runtime/JSGlobalData.h: Holds the cache. + * runtime/JSNumberCell.cpp: + (JSC::JSNumberCell::toString): + (JSC::JSNumberCell::toThisString): Removed -0 special case. + UString handles this now, since too many clients were + special-casing it. + + * runtime/JSString.h: + (JSC::JSValue::toString): Use the cache when converting + an int or double to string. + + * runtime/Operations.h: + (JSC::concatenateStrings): Call toString to take advantage + of the cache. + + * runtime/SmallStrings.h: + (JSC::NumericStrings::add): + (JSC::NumericStrings::lookup): The cache. + + * runtime/UString.cpp: + (JSC::UString::from): Added -0 special case mentioned above. + Removed appendNumeric because it's mutually exclusive with the + cache. + +2009-08-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + REGRESSION: fast/profiler/call.html is crashing occasionally + https://bugs.webkit.org/show_bug.cgi?id=28476 + + Using the codeblock for information about how many parameters and + locals a function has is unsafe in certain circumstances. The + basic scenario is all function code being cleared in response to + the debugger or profiler being enabled, and then an activation is + marked before its associated function is re-executed. + + To deal with this scenario we store the variable count of a function + directly in the FunctionExecutable, and then use that information. + + * runtime/Arguments.h: + (JSC::Arguments::getArgumentsData): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::generateBytecode): + * runtime/Executable.h: + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::FunctionExecutable::variableCount): + * runtime/JSActivation.cpp: + (JSC::JSActivation::markChildren): + +2009-08-20 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Numbering of arguments to emitGetJITStubArg/emitPutJITStubArg incorrect + <bug lost in the great bug disasteroony of 08/20/09!> + + The argumentNumber argument to emitGetJITStubArg/emitPutJITStubArg should match + the argument number used within the stub functions in JITStubs.cpp, but it doesn't. + + Firstly, all the numbers changed when we added a void* 'reserved' as the first slot + (rather than leaving argument 0 unused), and secondly in 32_64 builds the index to + peek/poke needs to be multiplies by 2 (since the argument to peek/poke is a number + of machine words, and on 32_64 build the argument slots to stub functions are two + words wide). + + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallSetupArgs): + (JSC::JIT::compileOpConstructSetupArgs): + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpCall): + * jit/JITInlineMethods.h: + (JSC::JIT::emitPutJITStubArg): + (JSC::JIT::emitPutJITStubArgConstant): + (JSC::JIT::emitGetJITStubArg): + (JSC::JIT::emitPutJITStubArgFromVirtualRegister): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + +2009-08-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + REGRESSION: significant slowdown on Celtic Kane "AJAX declaration" subtest + https://bugs.webkit.org/show_bug.cgi?id=28332 + + Follow up style fixes that were missed in review. + + * runtime/Structure.cpp: + (JSC::Structure::hasTransition): + * runtime/Structure.h: + (JSC::Structure::get): + (JSC::StructureTransitionTable::contains): + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTable::add): + +2009-08-20 Oliver Hunt <oliver@apple.com> + + Add new exports to windows jsc build + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + REGRESSION: significant slowdown on Celtic Kane "AJAX declaration" subtest + https://bugs.webkit.org/show_bug.cgi?id=28332 + + The method check optimisation made transitions aware of the value being + assigned when a transition was assigning a function. This had the side + effect of making every assignment of a function expression result in a + new transition, and thus a new Structure. The net result of this is that + the common JS idiom of + + function MyObject() { + this.myFunction = function(...){...}; + } + new MyObject(); + + Will produce a unique structure on every iteration, meaning that all + caching is defeated and there is a significant amount of structure churn. + + The fix is to return the transition to its original form where it is + keyed off a property name + attributes tuple, but have each transition + support an optional transition on a specific value. + + * JavaScriptCore.exp: + * runtime/JSObject.h: + (JSC::JSObject::putDirectInternal): + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::hasTransition): + * runtime/Structure.h: + (JSC::Structure::transitionedFor): + (JSC::Structure::hasTransition): + (JSC::Structure::): + (JSC::StructureTransitionTable::contains): + (JSC::StructureTransitionTable::get): + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTableHashTraits::emptyValue): + (JSC::StructureTransitionTable::hasTransition): + (JSC::StructureTransitionTable::remove): + (JSC::StructureTransitionTable::add): + +2009-08-20 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Remove FunctionCodeBlock. + https://bugs.webkit.org/show_bug.cgi?id=28502 + + These only exist to allow JIT code to dereference properties off the + CodeBlock for any callee, regardless of whether it is a host function. + + Instead just use the FunctionExecutable. Copy the m_parameters field + from the CodeBlock into the Executable, and use this to distinguish + between host functions, functions that have been bytecompiled, and + functions that have not. + + m_parameters is moved to ExecutableBase rather than FunctionExecutable + so that (as a separate change) we can move make a separate class of + executable for host code, which is not devived from FunctionExecutable + (host code does not feature any of the properties that normal executable + do and will provide, such as source, attributes, and a parsed name). + + 1% win on v8 tests, 0.5% on sunspider. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::derefStructures): + (JSC::CodeBlock::refStructures): + (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): + (JSC::CodeBlock::handlerForBytecodeOffset): + (JSC::CodeBlock::lineNumberForBytecodeOffset): + (JSC::CodeBlock::expressionRangeForBytecodeOffset): + (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset): + (JSC::CodeBlock::functionRegisterForBytecodeOffset): + (JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset): + (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset): + * bytecode/CodeBlock.h: + (JSC::): + (JSC::CodeBlock::source): + (JSC::CodeBlock::sourceOffset): + (JSC::CodeBlock::evalCodeCache): + (JSC::CodeBlock::createRareDataIfNecessary): + + remove NativeCodeBlocks and the NativeCode code type. + + * jit/JIT.cpp: + (JSC::JIT::linkCall): + + Revert to previous behaviour (as currently still commented!) that Hhost functions have a null codeblock. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallInitializeCallFrame): + (JSC::JIT::compileOpCallSetupArgs): + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpConstructSetupArgs): + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::compileOpCall): + (JSC::JIT::compileOpCallSlowCase): + + Bring the 32_64 & non-32_64 JITs into line with each other, callee in regT0. + + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + + Rewrite call trampolines to not use the CodeBlock. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + + Make call_JSFunction & call_arityCheck return the callee, don't expect to be passed the CodeBlock. + + * runtime/Executable.cpp: + (JSC::FunctionExecutable::generateBytecode): + (JSC::FunctionExecutable::recompile): + (JSC::FunctionExecutable::FunctionExecutable): + * runtime/Executable.h: + (JSC::ExecutableBase::): + (JSC::ExecutableBase::ExecutableBase): + (JSC::FunctionExecutable::isHostFunction): + + Add m_numParameters. + + * runtime/JSFunction.cpp: + (JSC::JSFunction::~JSFunction): + + Only call generatedBytecode() on JSFunctions non-host FunctionExecutables. + +2009-08-20 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=28054 + + Use a helper function to work around winscw compiler forward declaration bug + regarding templated classes. + + Add parenthesis around (PassRefPtr::*UnspecifiedBoolType) to make winscw compiler + work with the default UnSpecifiedBoolType() operator, which removes the winscw + specific bool cast hack. + + * wtf/PassRefPtr.h: + (WTF::derefIfNotNull): + (WTF::PassRefPtr::~PassRefPtr): + +2009-08-19 Yong Li <yong.li@torchmobile.com> + + Reviewed by Gavin Barraclough. + + Change namespace ARM to ARMRegisters + X86 to X86Registers to avoid conflict with macros + https://bugs.webkit.org/show_bug.cgi?id=28428 + + * assembler/ARMAssembler.cpp: + * assembler/ARMAssembler.h: + * assembler/ARMv7Assembler.h: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerARMv7.h: + * assembler/MacroAssemblerX86Common.h: + * assembler/MacroAssemblerX86_64.h: + * assembler/X86Assembler.h: + * jit/JIT.h: + * jit/JITArithmetic.cpp: + * jit/JITInlineMethods.h: + * jit/JITOpcodes.cpp: + * wrec/WRECGenerator.cpp: + * wrec/WRECGenerator.h: + * yarr/RegexJIT.cpp: + +2009-08-19 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Devirtualise marking + https://bugs.webkit.org/show_bug.cgi?id=28294 + + We actually need to mark the value in a number object if we're using the + 32bit number representation. + + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + +2009-08-19 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Darin Adler. + + We probably shouldn't be keeping the AST for eval nodes around forevar. + https://bugs.webkit.org/show_bug.cgi?id=28469 + + EvalNodes don't destroyData() (delete their parser data) since they need to hold onto + their varStack. Copy a list of variable onto EvalCodeBlock, and this can go away. + + * bytecode/CodeBlock.h: + (JSC::EvalCodeBlock::variable): + (JSC::EvalCodeBlock::numVariables): + (JSC::EvalCodeBlock::adoptVariables): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + * parser/Nodes.h: + * runtime/Executable.cpp: + (JSC::EvalExecutable::generateBytecode): + * runtime/Executable.h: + +2009-08-19 Jungshik Shin <jshin@chromium.org> + + Reviewed by Darin Adler. + + http://bugs.webkit.org/show_bug.cgi?id=28441 + + Fix a build issue with ICU 4.2 or later on Windows with Visual C++. + Instead of defining all isXXX and toupper/tolower as + WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h, + #define them to be different by prepending 'WTF_...ASCIIType_h' with + the originial names like 'toupper_WTF_...ASCIIType_h'. + + * wtf/DisallowCType.h: + +2009-08-18 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Assigning a function to an object should always use the existing transition, even if the transition is not specialized + https://bugs.webkit.org/show_bug.cgi?id=28442 + + Check for an unspecialized transition as an alternative to always failing if specialisation does not match. + + * runtime/Structure.cpp: + (JSC::Structure::addPropertyTransitionToExistingStructure): + +2009-08-18 Dirk Schulze <krit@webkit.org> + + Reviewed by Oliver Hunt. + + Added additional getter to ByteArray with an unsigned char as return. + ByteArray can take unsigned char directly now. + + * wtf/ByteArray.h: + (WTF::ByteArray::set): + (WTF::ByteArray::get): + +2009-08-18 Peter Kasting <pkasting@google.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=28415 + Set svn:eol-style CRLF on all .sln and .vcproj files that don't already + have it. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: + * JavaScriptCore.vcproj/testapi/testapi.vcproj: + +2009-08-18 Xan Lopez <xlopez@igalia.com> + + Try to fix the GTK+ build. + + * GNUmakefile.am: + +2009-08-17 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + No, silly runtime, AST nodes are not for you. + + We still use AST nodes (ScopeNodes, particularly FunctionBodyNodes) within + the runtime, which means that these nodes must be persisted outside of the + arena, contain both parser & runtime data, etc. This is all a bit of a mess. + + Move functionality into a new FunctionExecutable class. + + * API/JSCallbackFunction.cpp: + * API/JSObjectRef.cpp: + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::markAggregate): + (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): + (JSC::CodeBlock::lineNumberForBytecodeOffset): + (JSC::CodeBlock::shrinkToFit): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::getBytecodeIndex): + (JSC::CodeBlock::discardBytecode): + (JSC::CodeBlock::instructionCount): + (JSC::CodeBlock::getJITCode): + (JSC::CodeBlock::executablePool): + (JSC::CodeBlock::ownerExecutable): + (JSC::CodeBlock::extractExceptionInfo): + (JSC::CodeBlock::addFunctionDecl): + (JSC::CodeBlock::functionDecl): + (JSC::CodeBlock::numberOfFunctionDecls): + (JSC::CodeBlock::addFunctionExpr): + (JSC::CodeBlock::functionExpr): + (JSC::GlobalCodeBlock::GlobalCodeBlock): + (JSC::ProgramCodeBlock::ProgramCodeBlock): + (JSC::EvalCodeBlock::EvalCodeBlock): + (JSC::FunctionCodeBlock::FunctionCodeBlock): + (JSC::NativeCodeBlock::NativeCodeBlock): + * bytecode/EvalCodeCache.h: + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::doRun): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::emitNewFunction): + (JSC::BytecodeGenerator::emitNewFunctionExpression): + * bytecompiler/BytecodeGenerator.h: + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + * interpreter/CachedCall.h: + (JSC::CachedCall::CachedCall): + * interpreter/CallFrameClosure.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::throwException): + (JSC::Interpreter::execute): + (JSC::Interpreter::prepareForRepeatCall): + (JSC::Interpreter::debug): + (JSC::Interpreter::privateExecute): + (JSC::Interpreter::retrieveLastCaller): + * interpreter/Interpreter.h: + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JIT.h: + (JSC::JIT::compile): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::emit_op_new_func): + (JSC::JIT::emit_op_new_func_exp): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): + * parser/Nodes.cpp: + (JSC::FunctionBodyNode::reparseDataIfNecessary): + * parser/Nodes.h: + (JSC::EvalNode::partialDestroyData): + * parser/Parser.h: + * profiler/ProfileGenerator.cpp: + * profiler/Profiler.cpp: + (JSC::Profiler::createCallIdentifier): + (JSC::createCallIdentifierFromFunctionImp): + * runtime/Arguments.h: + (JSC::Arguments::getArgumentsData): + (JSC::Arguments::Arguments): + (JSC::JSActivation::copyRegisters): + * runtime/ArrayPrototype.cpp: + (JSC::isNumericCompareFunction): + * runtime/CallData.h: + (JSC::): + * runtime/Collector.cpp: + (JSC::Heap::collect): + * runtime/ConstructData.h: + (JSC::): + * runtime/ExceptionHelpers.cpp: + (JSC::createUndefinedVariableError): + (JSC::createInvalidParamError): + (JSC::createNotAConstructorError): + (JSC::createNotAFunctionError): + (JSC::createNotAnObjectError): + * runtime/Executable.cpp: Added. + (JSC::EvalExecutable::generateBytecode): + (JSC::ProgramExecutable::generateBytecode): + (JSC::FunctionExecutable::generateBytecode): + (JSC::EvalExecutable::generateJITCode): + (JSC::ProgramExecutable::generateJITCode): + (JSC::FunctionExecutable::generateJITCode): + (JSC::FunctionExecutable::isHostFunction): + (JSC::FunctionExecutable::markAggregate): + (JSC::FunctionExecutable::reparseExceptionInfo): + (JSC::EvalExecutable::reparseExceptionInfo): + (JSC::FunctionExecutable::recompile): + (JSC::FunctionExecutable::FunctionExecutable): + * runtime/Executable.h: + (JSC::ExecutableBase::~ExecutableBase): + (JSC::ExecutableBase::ExecutableBase): + (JSC::ExecutableBase::source): + (JSC::ExecutableBase::sourceID): + (JSC::ExecutableBase::lastLine): + (JSC::ExecutableBase::usesEval): + (JSC::ExecutableBase::usesArguments): + (JSC::ExecutableBase::needsActivation): + (JSC::ExecutableBase::astNode): + (JSC::ExecutableBase::generatedJITCode): + (JSC::ExecutableBase::getExecutablePool): + (JSC::EvalExecutable::EvalExecutable): + (JSC::EvalExecutable::bytecode): + (JSC::EvalExecutable::varStack): + (JSC::EvalExecutable::evalNode): + (JSC::EvalExecutable::jitCode): + (JSC::ProgramExecutable::ProgramExecutable): + (JSC::ProgramExecutable::reparseExceptionInfo): + (JSC::ProgramExecutable::bytecode): + (JSC::ProgramExecutable::programNode): + (JSC::ProgramExecutable::jitCode): + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::FunctionExecutable::name): + (JSC::FunctionExecutable::bytecode): + (JSC::FunctionExecutable::generatedBytecode): + (JSC::FunctionExecutable::usesEval): + (JSC::FunctionExecutable::usesArguments): + (JSC::FunctionExecutable::parameterCount): + (JSC::FunctionExecutable::paramString): + (JSC::FunctionExecutable::isGenerated): + (JSC::FunctionExecutable::body): + (JSC::FunctionExecutable::jitCode): + (JSC::FunctionExecutable::createNativeThunk): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunction): + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncToString): + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + (JSC::JSActivation::markChildren): + (JSC::JSActivation::isDynamicScope): + (JSC::JSActivation::argumentsGetter): + * runtime/JSActivation.h: + (JSC::JSActivation::JSActivationData::JSActivationData): + * runtime/JSFunction.cpp: + (JSC::JSFunction::isHostFunction): + (JSC::JSFunction::JSFunction): + (JSC::JSFunction::~JSFunction): + (JSC::JSFunction::markChildren): + (JSC::JSFunction::getCallData): + (JSC::JSFunction::call): + (JSC::JSFunction::lengthGetter): + (JSC::JSFunction::getConstructData): + (JSC::JSFunction::construct): + * runtime/JSFunction.h: + (JSC::JSFunction::executable): + (JSC::FunctionExecutable::make): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::numericCompareFunction): + * runtime/JSGlobalData.h: + +2009-08-17 Mark Rowe <mrowe@apple.com> + + Reviewed by Darin Adler. + + Fix 300,000+ leaks seen during the regression tests. + + EvalCodeCache::get was heap-allocating an EvalExecutable instance without adopting the initial reference. + While fixing this we noticed that EvalExecutable was a RefCounted type that was sometimes stack allocated. + To make this cleaner and to prevent clients from attempting to ref a stack-allocated instance, we move the + refcounting down to a new CacheableEvalExecutable class that derives from EvalExecutable. EvalCodeCache::get + now uses CacheableEvalExecutable::create and avoids the leak. + + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::callEval): + * runtime/Executable.h: + (JSC::CacheableEvalExecutable::create): + (JSC::CacheableEvalExecutable::CacheableEvalExecutable): + +2009-08-17 Oliver Hunt <oliver@apple.com> + + RS=Mark Rowe. + + REGRESSION (r47292): Prototype.js is broken by ES5 Arguments changes + https://bugs.webkit.org/show_bug.cgi?id=28341 + <rdar://problem/7145615> + + Reverting r47292. Alas Prototype.js breaks with Arguments inheriting + from Array as ES5 attempted. Prototype.js defines $A in terms of a + function it places on (among other global objects) the Array prototype, + thus breaking $A for arrays. + + * runtime/Arguments.h: + (JSC::Arguments::Arguments): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + (JSC::JSGlobalObject::markChildren): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::ObjectPrototype): + * runtime/ObjectPrototype.h: + * tests/mozilla/ecma_3/Function/arguments-001.js: + +2009-08-17 Peter Kasting <pkasting@google.com> + + Reviewed by Steve Falkenburg. + + https://bugs.webkit.org/show_bug.cgi?id=27323 + Only add Cygwin to the path when it isn't already there. This avoids + causing problems for people who purposefully have non-Cygwin versions of + executables like svn in front of the Cygwin ones in their paths. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: + * JavaScriptCore.vcproj/WTF/WTFCommon.vsprops: + * JavaScriptCore.vcproj/jsc/jscCommon.vsprops: + * JavaScriptCore.vcproj/testapi/testapiCommon.vsprops: + +2009-08-17 Xan Lopez <xlopez@igalia.com> + + Reviewed by Mark Rowe. + + Fix build with FAST_MALLOC_MATCH_VALIDATION enabled. + + * wtf/FastMalloc.cpp: + (WTF::fastMalloc): + (WTF::fastCalloc): + (WTF::fastRealloc): + +2009-08-16 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Mark Rowe. + + Fix crash on ./ecma_2/RegExp/exec-002.js. + https://bugs.webkit.org/show_bug.cgi?id=28353 + + Change the order of freeParenthesesDisjunctionContext and + popParenthesesDisjunctionContext on all call sites as the pop + method is accessing backTrack->lastContext which is the context + that is about to be freed. + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::Interpreter::parenthesesDoBacktrack): + (JSC::Yarr::Interpreter::backtrackParentheses): + +2009-08-16 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Mark Rowe. + + https://bugs.webkit.org/show_bug.cgi?id=28352 + + Fix coding style violations. Use m_ for C++ class members. Remove + trailing whitespace on empty lines. + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::ParenthesesDisjunctionContext): + (JSC::Yarr::Interpreter::tryConsumeCharacter): + (JSC::Yarr::Interpreter::tryConsumeBackReference): + (JSC::Yarr::Interpreter::parenthesesDoBacktrack): + (JSC::Yarr::Interpreter::backtrackParentheses): + (JSC::Yarr::ByteCompiler::ByteCompiler): + (JSC::Yarr::ByteCompiler::compile): + (JSC::Yarr::ByteCompiler::checkInput): + (JSC::Yarr::ByteCompiler::assertionBOL): + (JSC::Yarr::ByteCompiler::assertionEOL): + (JSC::Yarr::ByteCompiler::assertionWordBoundary): + (JSC::Yarr::ByteCompiler::atomPatternCharacter): + (JSC::Yarr::ByteCompiler::atomCharacterClass): + (JSC::Yarr::ByteCompiler::atomBackReference): + (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternBegin): + (JSC::Yarr::ByteCompiler::atomParentheticalAssertionBegin): + (JSC::Yarr::ByteCompiler::popParenthesesStack): + (JSC::Yarr::ByteCompiler::closeAlternative): + (JSC::Yarr::ByteCompiler::closeBodyAlternative): + (JSC::Yarr::ByteCompiler::atomParenthesesEnd): + (JSC::Yarr::ByteCompiler::regexBegin): + (JSC::Yarr::ByteCompiler::alterantiveBodyDisjunction): + (JSC::Yarr::ByteCompiler::alterantiveDisjunction): + (JSC::Yarr::ByteCompiler::emitDisjunction): + +2009-08-15 Mark Rowe <mrowe@apple.com> + + Fix the build with JIT disabled. + + * runtime/Arguments.h: Only compile the jitCode method when the JIT is enabled. + * runtime/Executable.h: Include PrototypeFunction.h so the compiler knows what + NativeFunctionWrapper is when the JIT is disabled. + +2009-08-15 Adam Bergkvist <adam.bergkvist@ericsson.com> + + Reviewed by Sam Weinig. + + Added ENABLE_EVENTSOURCE flag. + https://bugs.webkit.org/show_bug.cgi?id=14997 + + * Configurations/FeatureDefines.xcconfig: + +2009-08-14 Gavin Barraclough <barraclough@apple.com> + + * parser/Parser.h: + (JSC::EvalExecutable::parse): + (JSC::ProgramExecutable::parse): + * runtime/Executable.h: + +2009-08-14 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Remove AST nodes from use within the Runtime (outside of parsing), stage 1 + https://bugs.webkit.org/show_bug.cgi?id=28330 + + Remove the EvalNode and ProgramNode from use in the runtime. They still exist + after this patch, but are hidden behind EvalExecutable and FunctionExecutable, + and are also still reachable behind CodeBlock::m_ownerNode. + + The next step will be to beat back FunctionBodyNode in the same fashion. + Then remove the usage via CodeBlock, then only construct these nodes only on + demand during bytecode generation. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.h: + (JSC::GlobalCodeBlock::GlobalCodeBlock): + (JSC::GlobalCodeBlock::~GlobalCodeBlock): + (JSC::ProgramCodeBlock::ProgramCodeBlock): + (JSC::EvalCodeBlock::EvalCodeBlock): + (JSC::FunctionCodeBlock::FunctionCodeBlock): + (JSC::NativeCodeBlock::NativeCodeBlock): + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * debugger/Debugger.cpp: + (JSC::evaluateInGlobalCallFrame): + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::evaluate): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::callEval): + (JSC::Interpreter::execute): + * interpreter/Interpreter.h: + * parser/Nodes.cpp: + (JSC::FunctionBodyNode::createNativeThunk): + (JSC::FunctionBodyNode::generateBytecode): + (JSC::FunctionBodyNode::bytecodeForExceptionInfoReparse): + * parser/Parser.h: + (JSC::Parser::parse): + (JSC::Parser::reparse): + (JSC::Parser::parseFunctionFromGlobalCode): + (JSC::::parse): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/Error.cpp: + (JSC::throwError): + * runtime/Error.h: + * runtime/Executable.h: Added. + (JSC::TemplateExecutable::TemplateExecutable): + (JSC::TemplateExecutable::markAggregate): + (JSC::TemplateExecutable::sourceURL): + (JSC::TemplateExecutable::lineNo): + (JSC::TemplateExecutable::bytecode): + (JSC::TemplateExecutable::jitCode): + (JSC::EvalExecutable::EvalExecutable): + (JSC::ProgramExecutable::ProgramExecutable): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunction): + * runtime/FunctionConstructor.h: + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::numericCompareFunction): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::~JSGlobalObject): + (JSC::JSGlobalObject::markChildren): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::codeBlocks): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + +2009-08-14 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Rename the confusing isObject(<class>) to inherits(<class>). + It still works on non-objects, returning false. + + * runtime/ArrayConstructor.cpp: + (JSC::arrayConstructorIsArray): Removed unneeded isObject call + and updated remaining isObject call to new name, inherits. + + * runtime/JSCell.h: Renamed isObject(<class>) to inherits(<class>) + but more importantly, made it non-virtual (it was already inline) + so it is now as fast as JSObject::inherits was. + + * runtime/JSObject.h: Removed inherits function since the one + in the base class is fine as-is. Also made various JSCell functions + that should not be called on JSObject uncallable by making them + both private and not implemented. + (JSC::JSCell::inherits): Updated name. + (JSC::JSValue::inherits): Ditto. + + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + (JSC::arrayProtoFuncToLocaleString): + (JSC::arrayProtoFuncConcat): + * runtime/BooleanPrototype.cpp: + (JSC::booleanProtoFuncToString): + (JSC::booleanProtoFuncValueOf): + * runtime/DateConstructor.cpp: + (JSC::constructDate): + * runtime/DatePrototype.cpp: + (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::dateProtoFuncGetMilliSeconds): + (JSC::dateProtoFuncGetUTCMilliseconds): + (JSC::dateProtoFuncGetTimezoneOffset): + (JSC::dateProtoFuncSetTime): + (JSC::setNewValueFromTimeArgs): + (JSC::setNewValueFromDateArgs): + (JSC::dateProtoFuncSetYear): + (JSC::dateProtoFuncGetYear): + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncToString): + * runtime/JSActivation.cpp: + (JSC::JSActivation::argumentsGetter): + * runtime/JSValue.h: + * runtime/RegExpConstructor.cpp: + (JSC::constructRegExp): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncTest): + (JSC::regExpProtoFuncExec): + (JSC::regExpProtoFuncCompile): + (JSC::regExpProtoFuncToString): + * runtime/ScopeChain.cpp: + (JSC::ScopeChain::localDepth): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncToString): + (JSC::stringProtoFuncMatch): + (JSC::stringProtoFuncSearch): + (JSC::stringProtoFuncSplit): + Updated to new name, inherits, from old name, isObject. + +2009-07-31 Harald Fernengel <harald.fernengel@nokia.com> + + Reviewed by Simon Hausmann. + + Adding QNX as a platform. Currently only tested with Qt. + + https://bugs.webkit.org/show_bug.cgi?id=27885 + + * JavaScriptCore/runtime/Collector.cpp: Added retrieving of stack base + since QNX doesn't have the pthread _nt functions + * JavaScriptCore/wtf/Platform.h: Added WTF_PLATFORM_QNX and corresponding + defines + * WebCore/bridge/npapi.h: Build fix for missing typedefs on QNX + +2009-08-14 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + Currently generic ARM and ARMv7 platforms work only with JSVALUE32 + https://bugs.webkit.org/show_bug.cgi?id=28300 + + * wtf/Platform.h: + +2009-08-14 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + Enable JIT on ARM for QT by default + https://bugs.webkit.org/show_bug.cgi?id=28259 + + * wtf/Platform.h: + +2009-08-14 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + Enable YARR_JIT on ARM for QT by default + https://bugs.webkit.org/show_bug.cgi?id=28259 + + * wtf/Platform.h: + +2009-08-14 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + [ES5] Arguments object should inherit from Array + https://bugs.webkit.org/show_bug.cgi?id=28298 + + Make the Arguments object conform to the behaviour specified in ES5. + The simple portion of this is to make Arguments use Array.prototype + as its prototype rather than Object.prototype. + + The spec then requires us to set instance.constructor to the pristine + Object constructor, and instance.toString and instance.toLocaleString + to the pristine versions from Object.prototype. To do this we now + make the ObjectPrototype constructor return its toString and + toLocaleString functions (similar to the call and apply functions + from FunctionPrototype). + + Oddly enough this reports itself as a slight win, but given the code + isn't hit in the tests that claim to have improved I put this down to + code motion. + + * runtime/Arguments.h: + (JSC::Arguments::Arguments): + (JSC::Arguments::initializeStandardProperties): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + (JSC::JSGlobalObject::markChildren): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): + (JSC::JSGlobalObject::objectConstructor): + (JSC::JSGlobalObject::objectToStringFunction): + (JSC::JSGlobalObject::objectToLocaleStringFunction): + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::ObjectPrototype): + * runtime/ObjectPrototype.h: + * tests/mozilla/ecma_3/Function/arguments-001.js: + Update test to new es5 behaviour + +2009-08-14 Oliver Hunt <oliver@apple.com> + + Remove MarkStack::drain from the JSC exports file + + MarkStack::drain is now marked inline, the including it in the exports file + produces an ld warning + + * JavaScriptCore.exp: + +2009-08-13 Sam Weinig <sam@webkit.org> + + Reviewed by Oliver Hunt. + + Remove accidentally left in debugging statement. + + * runtime/JSArray.h: + (JSC::MarkStack::drain): + +2009-08-13 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + [ES5] Implement Array.isArray + https://bugs.webkit.org/show_bug.cgi?id=28296 + + Add support for Array.isArray to the Array constructor + + * runtime/ArrayConstructor.cpp: + (JSC::ArrayConstructor::ArrayConstructor): + (JSC::arrayConstructorIsArray): + * runtime/ArrayConstructor.h: + * runtime/CommonIdentifiers.h: + * runtime/JSArray.h: + (JSC::MarkStack::drain): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + +2009-08-13 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Buildfix). + + Attempt to fix windows build + + * runtime/Collector.cpp: + +2009-08-13 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Devirtualise marking + https://bugs.webkit.org/show_bug.cgi?id=28294 + + Add a bit to TypeInfo to indicate that an object uses the standard + JSObject::markChildren method. This allows us to devirtualise marking + of most objects (though a branch is still needed). We also add a branch + to identify arrays thus devirtualising marking in that case as well. + + In order to make the best use of this devirtualisation I've also reworked + the MarkStack::drain() logic to make the iteration more efficient. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * JavaScriptCore.exp: + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::JSAPIValueWrapper): + * runtime/JSArray.cpp: + (JSC::JSArray::markChildren): + * runtime/JSArray.h: + (JSC::JSArray::markChildrenDirect): + (JSC::MarkStack::drain): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSCell.h: + (JSC::MarkStack::append): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.cpp: + (JSC::JSObject::markChildren): + * runtime/JSObject.h: + (JSC::JSObject::markChildrenDirect): + (JSC::JSObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSType.h: + (JSC::): + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStack): + (JSC::MarkStack::MarkSet::MarkSet): + (JSC::MarkStack::MarkStackArray::last): + * 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/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + * runtime/TypeInfo.h: + (JSC::TypeInfo::hasDefaultMark): + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by Mark Rowe. + + Some small bits of housekeeping. + + * JavaScriptCore.xcodeproj/project.pbxproj: Make Parser.h + project instead of private. Remove JSONObject.lut.h. + + * assembler/ARMAssembler.h: Remove unneeded WTF prefix. + * assembler/AssemblerBufferWithConstantPool.h: Ditto. + * bytecompiler/BytecodeGenerator.h: Ditto. + + * wtf/SegmentedVector.h: Add a "using" statement as we do + with the other WTF headers. + +2009-08-13 Darin Adler <darin@apple.com> + + Fix Tiger build. + + * parser/Grammar.y: Use a template function so we can compile + setStatementLocation even if it comes before YYLTYPE is defined. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + Too much use of void* in Grammar.y + https://bugs.webkit.org/show_bug.cgi?id=28287 + + * parser/Grammar.y: Changed all the helper functions to + take a JSGlobalData* instead of a void*. A couple formatting + tweaks that I missed when breaking this into pieces. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + Another part of https://bugs.webkit.org/show_bug.cgi?id=28287 + + * parser/Grammar.y: Reduced and sorted includes. Tweaked comment + format. Marked a few more functions inline. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + Another part of https://bugs.webkit.org/show_bug.cgi?id=28287 + + * parser/Grammar.y: Pass the number to the PropertyNode instead of + first turning it into an Identifier. + + * parser/NodeConstructors.h: + (JSC::PropertyNode::PropertyNode): Add an overload that takes a double + so the code to convert to a string can be here instead of Grammar.y. + * parser/Nodes.h: Ditto. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + Another part of https://bugs.webkit.org/show_bug.cgi?id=28287 + + * parser/Grammar.y: Eliminate the DBG macro. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + Another part of https://bugs.webkit.org/show_bug.cgi?id=28287 + + * parser/Grammar.y: Eliminate the SET_EXCEPTION_LOCATION macro. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by George Staikos. + + George asked me to break the patch from + https://bugs.webkit.org/show_bug.cgi?id=28287 + into smaller pieces and land it in stages. + + * parser/Grammar.y: Eliminate the LEXER macro. + +2009-08-13 Mark Rowe <mrowe@apple.com> + + Try some more to fix the Windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export a new symbol. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Ditto. + +2009-08-13 Mark Rowe <mrowe@apple.com> + + Try and fix the Windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export a new symbol. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Ditto. + +2009-08-13 Darin Adler <darin@apple.com> + + Reviewed by David Levin. + + JavaScriptCore tweaks to get ready for the parser arena + https://bugs.webkit.org/show_bug.cgi?id=28243 + + Eliminate dependencies on Nodes.h outside JavaScriptCore, + and cut down on them inside JavaScriptCore. + + Change regular expression parsing to use identifiers as + with other strings we parse. + + Fix a couple things that are needed to use const Identifier + more, which will be part of the parser arena work. + + * JavaScriptCore.exp: Resorted and updated. + + * JavaScriptCore.xcodeproj/project.pbxproj: Changed + CollectorHeapIterator.h to be project-internal. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitPushNewScope): Added const. + * bytecompiler/BytecodeGenerator.h: Ditto. + + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): Moved this function + here from WebCore. Here is better since it uses so many internals. + Removed unimportant optimization for the no listener case. + * debugger/Debugger.h: Ditto. Also removed unneeded include + and tweaked formatting and comments. + + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::functionName): Call asFunction instead + of doing the unchecked static_cast. + (JSC::DebuggerCallFrame::calculatedFunctionName): Ditto. + + * jit/JITStubs.cpp: + (JSC::op_call_JSFunction): Call isHostFunction on the body rather + than on the JSFunction. + (JSC::vm_lazyLinkCall): Ditto. + (JSC::op_construct_JSConstruct): Ditto. + + * parser/Grammar.y: Changed callers to use new scanRegExp with + out arguments instead of relying on state in the Lexer. And + callers that just want to skip a regular expression to use + skipRegExp. + + * parser/Lexer.cpp: + (JSC::Lexer::scanRegExp): Changed to use out arguments, and to + add a prefix argument so we can add in the "=" character as needed. + Also rewrote to streamline the logic a bit inspired by suggestions + by David Levin. + (JSC::Lexer::skipRegExp): Added. Version of the function above that + does not actually put the regular expression into a string. + (JSC::Lexer::clear): Removed code to clear m_pattern and m_flags. + * parser/Lexer.h: Changed scanRegExp to have out arguments. Added + skipRegExp. Eliminated pattern, flags, m_pattern, and m_flags. + + * parser/NodeConstructors.h: + (JSC::RegExpNode::RegExpNode): Changed to take const Identifier&. + * parser/Nodes.cpp: + (JSC::RegExpNode::emitBytecode): Changed since m_pattern and + m_flags are now Identifier instead of UString. + (JSC::FunctionBodyNode::make): Moved this function here instead + of putting it in the JSFunction.h header. + * parser/Nodes.h: Changed RegExpNode to use Identifier. + + * profiler/Profiler.cpp: + (JSC::Profiler::createCallIdentifier): Changed to use isHostFunction + on the body instead of on the JSFunction object. + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncToString): Ditto. + + * runtime/JSFunction.cpp: + (JSC::JSFunction::isHostFunction): Moved here from header. + (JSC::JSFunction::isHostFunctionNonInline): Added. + (JSC::JSFunction::JSFunction): Removed unneeded initialization of + m_body to 0. + (JSC::JSFunction::setBody): Moved here from header. + + * runtime/JSFunction.h: Removed unneeded includes. Moved private + constructor down to the private section. Made virtual functions + private. Removed unneeded overload of setBody and moved the body + of the function into the .cpp file. Changed assertions to use + the non-inline version of isHostFunction. + + * runtime/PropertySlot.cpp: + (JSC::PropertySlot::functionGetter): Use asFunction instead + of doing the unchecked static_cast. + + * wtf/SegmentedVector.h: + (WTF::SegmentedVector::isEmpty): Added. + +2009-08-13 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Darin Adler. + + Use the version of operator new that takes a JSGlobalData when allocating FuncDeclNode and FuncExprNode + from within the grammar to prevent these nodes from being leaked. + + * parser/Grammar.y: + +2009-08-13 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Ariya Hidayat. + + Remove the special-case for Qt wrt JSVALUE_32 introduced in + r46709. It must've been a dependency issue on the bot, as + after a manual build all the tests pass on amd64 and ia32. + + * wtf/Platform.h: + +2009-08-12 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Add optimize call and property access support for ARM JIT. + https://bugs.webkit.org/show_bug.cgi?id=24986 + + For tightly coupled sequences the BEGIN_UNINTERRUPTED_SEQUENCE and + END_UNINTERRUPTED_SEQUENCE macros have been introduced which ensure + space for instructions and constants of the named sequence. This + method is vital for those architecture which are using constant pool. + + The 'latePatch' method - which was linked to JmpSrc - is replaced with + a port specific solution (each calls are marked to place their address + on the constant pool). + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::linkBranch): + (JSC::ARMAssembler::executableCopy): Add extra align for constant pool. + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::JmpSrc::JmpSrc): + (JSC::ARMAssembler::sizeOfConstantPool): + (JSC::ARMAssembler::jmp): + (JSC::ARMAssembler::linkCall): + * assembler/ARMv7Assembler.h: + * assembler/AbstractMacroAssembler.h: + * assembler/AssemblerBufferWithConstantPool.h: + (JSC::AssemblerBufferWithConstantPool::flushIfNoSpaceFor): Fix the + computation of the remaining space. + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::branch32): + (JSC::MacroAssemblerARM::nearCall): + (JSC::MacroAssemblerARM::call): + (JSC::MacroAssemblerARM::branchPtrWithPatch): + (JSC::MacroAssemblerARM::ensureSpace): + (JSC::MacroAssemblerARM::sizeOfConstantPool): + (JSC::MacroAssemblerARM::prepareCall): + * assembler/X86Assembler.h: + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITInlineMethods.h: + (JSC::JIT::beginUninterruptedSequence): + (JSC::JIT::endUninterruptedSequence): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compileGetByIdSlowCase): + (JSC::JIT::emit_op_put_by_id): + +2009-08-12 Gavin Barraclough <barraclough@apple.com> + + Rubber Stamped by Dave Kilzer. + + Disable WTF_USE_JSVALUE32_64 on iPhone for now (support not yet added for ARMv7). + + * wtf/Platform.h: + +2009-08-12 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Maciej Stachoviak. + + Ooops - moved code that had been accidentally added to op_new_func instead of + op_new_func_exp, to where it shoulds be. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * wtf/Platform.h: + +2009-08-12 Ada Chan <adachan@apple.com> + + Added workaround for the limitation that VirtualFree with MEM_RELEASE + can only accept the base address returned by VirtualAlloc when the region + was reserved and it can only free the entire region, and not a part of it. + + Reviewed by Oliver Hunt. + + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + * runtime/MarkStackWin.cpp: + (JSC::MarkStack::releaseStack): + +2009-08-12 Balazs Kelemen <kelemen.balazs.3@stud.u-szeged.hu> + + Reviewed by Ariya Hidayat. + + Build fix: use std::numeric_limits<long long>::min() instead of LLONG_MIN + since LLONG_MIN is not defined in standard c++. + + * runtime/UString.cpp: + (JSC::UString::from): + +2009-08-12 Benjamin Otte <otte@gnome.org> + + Reviewed by Jan Alonzo. + + Buildfix for Gtk platforms debug builds. + + * GNUmakefile.am: Choose MarkStackPosix.cpp or MarkStackWin.cpp + depending on platform. + +2009-08-12 Simon Hausmann <simon.hausmann@nokia.com> + + Prospective build fix for Mac and 32-bit Windows. + + * runtime/UString.cpp: Include wtf/StringExtras.h for snprintf. + (JSC::UString::from): Use %lld instead of %I64d for snprintf + on non-windows platforms. + +2009-08-12 Prasanth Ullattil <prasanth.ullattil@nokia.com> + + Reviewed by Simon Hausmann. + + Fix compile error on 64Bit Windows, when UString::from + is called with an intptr_t. + + Added new UString::From overload with long long parameter. + + Thanks to Holger for the long long idea. + + * runtime/UString.cpp: + (JSC::UString::from): + * runtime/UString.h: + +2009-08-11 Oliver Hunt <oliver@apple.com> + + Reviewed by Mark Rowe. + + Minor style fixes. + + * runtime/UString.h: + (JSC::UString::Rep::createEmptyBuffer): + * wtf/FastMalloc.h: + (WTF::TryMallocReturnValue::getValue): + +2009-08-11 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Make it harder to misuse try* allocation routines + https://bugs.webkit.org/show_bug.cgi?id=27469 + + Jump through a few hoops to make it much harder to accidentally + miss null-checking of values returned by the try-* allocation + routines. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSArray.cpp: + (JSC::JSArray::putSlowCase): + (JSC::JSArray::increaseVectorLength): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncLink): + * runtime/UString.cpp: + (JSC::allocChars): + (JSC::reallocChars): + (JSC::expandCapacity): + (JSC::UString::Rep::reserveCapacity): + (JSC::UString::expandPreCapacity): + (JSC::createRep): + (JSC::concatenate): + (JSC::UString::spliceSubstringsWithSeparators): + (JSC::UString::replaceRange): + (JSC::UString::append): + (JSC::UString::operator=): + * runtime/UString.h: + (JSC::UString::Rep::createEmptyBuffer): + * wtf/FastMalloc.cpp: + (WTF::tryFastZeroedMalloc): + (WTF::tryFastMalloc): + (WTF::tryFastCalloc): + (WTF::tryFastRealloc): + (WTF::TCMallocStats::tryFastMalloc): + (WTF::TCMallocStats::tryFastCalloc): + (WTF::TCMallocStats::tryFastRealloc): + * wtf/FastMalloc.h: + (WTF::TryMallocReturnValue::TryMallocReturnValue): + (WTF::TryMallocReturnValue::~TryMallocReturnValue): + (WTF::TryMallocReturnValue::operator PossiblyNull<T>): + (WTF::TryMallocReturnValue::getValue): + * wtf/Platform.h: + * wtf/PossiblyNull.h: Added. + (WTF::PossiblyNull::PossiblyNull): + (WTF::PossiblyNull::~PossiblyNull): + (WTF::::getValue): + +2009-08-11 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix part deux). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-11 Gavin Barraclough <barraclough@apple.com> + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-11 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Restrict use of FuncDeclNode & FuncExprNode to the parser. + https://bugs.webkit.org/show_bug.cgi?id=28209 + + These objects were also being referenced from the CodeBlock. By changing this + to just retain pointers to FunctionBodyNodes these classes can be restricted to + use during parsing. + + No performance impact (or sub-percent progression). + + * JavaScriptCore.exp: + Update symbols. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::mark): + (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): + (JSC::CodeBlock::shrinkToFit): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::addFunction): + (JSC::CodeBlock::function): + Unify m_functions & m_functionExpressions into a single Vector<RefPtr<FuncExprNode> >. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::emitNewFunction): + (JSC::BytecodeGenerator::emitNewFunctionExpression): + * bytecompiler/BytecodeGenerator.h: + FunctionStacks now contain FunctionBodyNodes not FuncDeclNodes. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + (JSC::Interpreter::privateExecute): + Update to reflect chnages in CodeBlock. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_func_exp): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): + Update to reflect chnages in CodeBlock. + + * parser/Grammar.y: + FunctionStacks now contain FunctionBodyNodes not FuncDeclNodes. + + * parser/NodeConstructors.h: + (JSC::FuncExprNode::FuncExprNode): + (JSC::FuncDeclNode::FuncDeclNode): + * parser/Nodes.cpp: + (JSC::ScopeNodeData::mark): + (JSC::FunctionBodyNode::finishParsing): + * parser/Nodes.h: + (JSC::FunctionBodyNode::ident): + Move m_ident & make methods from FuncDeclNode & FuncExprNode to FunctionBodyNode. + + * runtime/JSFunction.h: + (JSC::FunctionBodyNode::make): + Make this method inline (was FuncDeclNode::makeFunction). + +2009-08-11 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Native JSON.stringify does not omit functions + https://bugs.webkit.org/show_bug.cgi?id=28117 + + Objects that are callable should be treated as undefined when + serialising to JSON. + + * runtime/JSONObject.cpp: + (JSC::Stringifier::appendStringifiedValue): + +2009-08-11 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + REGRESSION: Hang/crash in BytecodeGenerator::constRegisterFor loading simple page + https://bugs.webkit.org/show_bug.cgi?id=28169 + + Handle the case where someone has attempted to shadow a property + on the global object with a constant. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::constRegisterFor): + * parser/Nodes.cpp: + (JSC::ConstDeclNode::emitCodeSingle): + +2009-08-11 John Gregg <johnnyg@google.com> + + Reviewed by Maciej Stachowiak. + + Desktop Notifications API + https://bugs.webkit.org/show_bug.cgi?id=25463 + + Adds ENABLE_NOTIFICATION flag. + + * Configurations/FeatureDefines.xcconfig: + * wtf/Platform.h: + +2009-08-11 Maxime Simon <simon.maxime@gmail.com> + + Reviewed by Eric Seidel. + + Modifications on JavaScriptCore to allow Haiku port. + https://bugs.webkit.org/show_bug.cgi?id=28121 + + * runtime/Collector.cpp: Haiku doesn't have sys/mman.h, using OS.h instead. + (JSC::currentThreadStackBase): Haiku uses its own threading system. + * wtf/Platform.h: Defining all Haiku platform values. + * wtf/haiku/MainThreadHaiku.cpp: Adding a missing header (NotImplemented.h). + +2009-08-11 Jessie Berlin <jberlin@apple.com> + + Reviewed by Adam Roben. + + Fix windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-11 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + Buildfix for Qt-win platforms. + + * JavaScriptCore.pri: Choose MarkStackPosix.cpp or MarkStackWin.cpp depend on platform. + +2009-08-10 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (And another build fix). + + Add new exports for MSVC + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-08-10 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (yet another build fix). + + Remove obsolete entries from MSVC exports file + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-10 Oliver Hunt <oliver@apple.com> + + Add includes needed for non-allinonefile builds + + * runtime/GetterSetter.h: + * runtime/ScopeChain.h: + +2009-08-10 Oliver Hunt <oliver@apple.com> + + Fix export file for last build fix + + * JavaScriptCore.exp: + +2009-08-10 Oliver Hunt <oliver@apple.com> + + Hoist page size initialization into platform specific code. + + * jit/ExecutableAllocatorPosix.cpp: + * jit/ExecutableAllocatorWin.cpp: + * runtime/MarkStack.h: + (JSC::MarkStack::pageSize): + * runtime/MarkStackPosix.cpp: + (JSC::MarkStack::initializePagesize): + * runtime/MarkStackWin.cpp: + (JSC::MarkStack::initializePagesize): + +2009-08-07 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Stack overflow crash in JavaScript garbage collector mark pass + https://bugs.webkit.org/show_bug.cgi?id=12216 + + Make the GC mark phase iterative by using an explicit mark stack. + To do this marking any single object is performed in multiple stages + * The object is appended to the MarkStack, this sets the marked + bit for the object using the new markDirect() function, and then + returns + * When the MarkStack is drain()ed the object is popped off the stack + and markChildren(MarkStack&) is called on the object to collect + all of its children. drain() then repeats until the stack is empty. + + Additionally I renamed a number of methods from 'mark' to 'markAggregate' + in order to make it more clear that marking of those object was not + going to result in an actual recursive mark. + + * GNUmakefile.am + * JavaScriptCore.exp: + * JavaScriptCore.gypi: + * JavaScriptCore.pri: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::markAggregate): + * bytecode/CodeBlock.h: + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::markAggregate): + * debugger/DebuggerActivation.cpp: + (JSC::DebuggerActivation::markChildren): + * debugger/DebuggerActivation.h: + * interpreter/Register.h: + * interpreter/RegisterFile.h: + (JSC::RegisterFile::markGlobals): + (JSC::RegisterFile::markCallFrames): + * parser/Nodes.cpp: + (JSC::ScopeNodeData::markAggregate): + (JSC::EvalNode::markAggregate): + (JSC::FunctionBodyNode::markAggregate): + * parser/Nodes.h: + (JSC::ScopeNode::markAggregate): + * runtime/ArgList.cpp: + (JSC::MarkedArgumentBuffer::markLists): + * runtime/ArgList.h: + * runtime/Arguments.cpp: + (JSC::Arguments::markChildren): + * runtime/Arguments.h: + * runtime/Collector.cpp: + (JSC::Heap::markConservatively): + (JSC::Heap::markCurrentThreadConservativelyInternal): + (JSC::Heap::markCurrentThreadConservatively): + (JSC::Heap::markOtherThreadConservatively): + (JSC::Heap::markStackObjectsConservatively): + (JSC::Heap::markProtectedObjects): + (JSC::Heap::collect): + * runtime/Collector.h: + * runtime/GetterSetter.cpp: + (JSC::GetterSetter::markChildren): + * runtime/GetterSetter.h: + (JSC::GetterSetter::GetterSetter): + (JSC::GetterSetter::createStructure): + * runtime/GlobalEvalFunction.cpp: + (JSC::GlobalEvalFunction::markChildren): + * runtime/GlobalEvalFunction.h: + * runtime/JSActivation.cpp: + (JSC::JSActivation::markChildren): + * runtime/JSActivation.h: + * runtime/JSArray.cpp: + (JSC::JSArray::markChildren): + * runtime/JSArray.h: + * runtime/JSCell.h: + (JSC::JSCell::markCellDirect): + (JSC::JSCell::markChildren): + (JSC::JSValue::markDirect): + (JSC::JSValue::markChildren): + (JSC::JSValue::hasChildren): + (JSC::MarkStack::append): + (JSC::MarkStack::drain): + * runtime/JSFunction.cpp: + (JSC::JSFunction::markChildren): + * runtime/JSFunction.h: + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + * runtime/JSGlobalObject.cpp: + (JSC::markIfNeeded): + (JSC::JSGlobalObject::markChildren): + * runtime/JSGlobalObject.h: + * runtime/JSNotAnObject.cpp: + (JSC::JSNotAnObject::markChildren): + * runtime/JSNotAnObject.h: + * runtime/JSONObject.cpp: + (JSC::Stringifier::markAggregate): + (JSC::JSONObject::markStringifiers): + * runtime/JSONObject.h: + * runtime/JSObject.cpp: + (JSC::JSObject::markChildren): + (JSC::JSObject::defineGetter): + (JSC::JSObject::defineSetter): + * runtime/JSObject.h: + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::markChildren): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::createStructure): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + (JSC::JSPropertyNameIterator::create): + * runtime/JSStaticScopeObject.cpp: + (JSC::JSStaticScopeObject::markChildren): + * runtime/JSStaticScopeObject.h: + * runtime/JSType.h: + (JSC::): + * runtime/JSValue.h: + * runtime/JSWrapperObject.cpp: + (JSC::JSWrapperObject::markChildren): + * runtime/JSWrapperObject.h: + * runtime/MarkStack.cpp: Added. + (JSC::MarkStack::compact): + * runtime/MarkStack.h: Added. + (JSC::): + (JSC::MarkStack::MarkStack): + (JSC::MarkStack::append): + (JSC::MarkStack::appendValues): + (JSC::MarkStack::~MarkStack): + (JSC::MarkStack::MarkSet::MarkSet): + (JSC::MarkStack::pageSize): + + MarkStackArray is a non-shrinking, mmap-based vector type + used for storing objects to be marked. + (JSC::MarkStack::MarkStackArray::MarkStackArray): + (JSC::MarkStack::MarkStackArray::~MarkStackArray): + (JSC::MarkStack::MarkStackArray::expand): + (JSC::MarkStack::MarkStackArray::append): + (JSC::MarkStack::MarkStackArray::removeLast): + (JSC::MarkStack::MarkStackArray::isEmpty): + (JSC::MarkStack::MarkStackArray::size): + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + * runtime/MarkStackPosix.cpp: Added. + (JSC::MarkStack::allocateStack): + (JSC::MarkStack::releaseStack): + * runtime/MarkStackWin.cpp: Added. + (JSC::MarkStack::allocateStack): + (JSC::MarkStack::releaseStack): + + * runtime/ScopeChain.h: + * runtime/ScopeChainMark.h: + (JSC::ScopeChain::markAggregate): + * runtime/SmallStrings.cpp: + (JSC::SmallStrings::mark): + * runtime/Structure.h: + (JSC::Structure::markAggregate): + +2009-08-10 Mark Rowe <mrowe@apple.com> + + Reviewed by Darin Adler. + + Fix hundreds of "pointer being freed was not allocated" errors seen on the build bot. + + * wtf/FastMalloc.h: Implement nothrow variants of the delete and delete[] operators since + we implement the nothrow variants of new and new[]. The nothrow variant of delete is called + explicitly in the implementation of std::sort which was resulting in FastMalloc-allocated + memory being passed to the system allocator to free. + +2009-08-10 Jan Michael Alonzo <jmalonzo@webkit.org> + + [Gtk] Unreviewed build fix. Move JSAPIValueWrapper.cpp/.h in the debug + section. This file is already part of AllInOneFile in Release builds. + + * GNUmakefile.am: + +2009-08-10 Darin Adler <darin@apple.com> + + * wtf/FastMalloc.h: Fix build. + +2009-08-10 Darin Adler <darin@apple.com> + + Reviewed by Mark Rowe. + + FastMalloc.h has cross-platform code but marked as WinCE-only + https://bugs.webkit.org/show_bug.cgi?id=28160 + + 1) The support for nothrow was inside #if PLATFORM(WINCE) even though it is + not platform-specific. + 2) The code tried to override operator delete nothrow, which does not exist. + 3) The code in the header checks the value of USE_SYSTEM_MALLOC, but the code + in FastMalloc.cpp checks only if the macro is defined. + + * wtf/FastMalloc.h: See above. + * wtf/FastMalloc.cpp: Ditto. + +2009-08-10 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + Fix an annoying indentation issue. + + * runtime/DateConstructor.cpp: + (JSC::constructDate): + +2009-08-10 Xan Lopez <xlopez@igalia.com> + + Unreviewed build fix. + + Add new files to makefile. + + * GNUmakefile.am: + +2009-08-10 Simon Hausmann <simon.hausmann@nokia.com> + + Fix compilation with the interpreter instead of the JIT by including + PrototypeFunction.h as forward-declared through NativeFunctionWrapper.h. + + * runtime/ObjectConstructor.cpp: + +2009-08-09 Oliver Hunt <oliver@apple.com> + + Reviewed by George Staikos. + + JSON.stringify replacer returning undefined does not omit object properties + https://bugs.webkit.org/show_bug.cgi?id=28118 + + Correct behaviour of stringify when using a replacer function that returns + undefined. This is a simple change to move the undefined value check to + after the replacer function is called. This means that the replacer function + is now called for properties with the value undefined, however i've confirmed + that this behaviour is correct. + + In addition I've made the cyclic object exception have a more useful error + message. + + * runtime/JSONObject.cpp: + (JSC::Stringifier::appendStringifiedValue): + +2009-08-08 Oliver Hunt <oliver@apple.com> + + Reviewed by Eric Seidel and Sam Weinig. + + [ES5] Implement Object.getPrototypeOf + https://bugs.webkit.org/show_bug.cgi?id=28114 + + Implement getPrototypeOf + + * runtime/CommonIdentifiers.h: + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConsGetPrototypeOf): + * runtime/ObjectConstructor.h: + +2009-08-07 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Eric Seidel. + + Allow custom memory allocation control for Noncopyable class + https://bugs.webkit.org/show_bug.cgi?id=27879 + + Several classes which are inherited from Noncopyable are instantiated by + operator new, so Noncopyable class has been inherited from FastAllocBase. + + * wtf/Noncopyable.h: + +2009-08-07 George Staikos <george.staikos@torchmobile.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=27305 + Implement WinCE-specific unicode layer. + Written by George Staikos <george.staikos@torchmobile.com> + with bug fixes by Yong Li <yong.li@torchmobile.com> + refactored by Joe Mason <joe.mason@torchmobile.com> + + * wtf/Platform.h: + * wtf/unicode/Unicode.h: + * wtf/unicode/wince/UnicodeWince.cpp: Added. + (WTF::Unicode::toLower): + (WTF::Unicode::toUpper): + (WTF::Unicode::foldCase): + (WTF::Unicode::isPrintableChar): + (WTF::Unicode::isSpace): + (WTF::Unicode::isLetter): + (WTF::Unicode::isUpper): + (WTF::Unicode::isLower): + (WTF::Unicode::isDigit): + (WTF::Unicode::isPunct): + (WTF::Unicode::toTitleCase): + (WTF::Unicode::direction): + (WTF::Unicode::category): + (WTF::Unicode::decompositionType): + (WTF::Unicode::combiningClass): + (WTF::Unicode::mirroredChar): + (WTF::Unicode::digitValue): + * wtf/unicode/wince/UnicodeWince.h: Added. + (WTF::Unicode::): + (WTF::Unicode::isSeparatorSpace): + (WTF::Unicode::isHighSurrogate): + (WTF::Unicode::isLowSurrogate): + (WTF::Unicode::isArabicChar): + (WTF::Unicode::hasLineBreakingPropertyComplexContext): + (WTF::Unicode::umemcasecmp): + (WTF::Unicode::surrogateToUcs4): + +2009-08-07 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=28069 + + Add inline to help winscw compiler resolve specialized argument in + templated functions. + + * runtime/LiteralParser.cpp: + (JSC::LiteralParser::Lexer::lexString): + +2009-08-07 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Eric Seidel. + + Allow custom memory allocation control for RegExpObjectData struct + http://bugs.webkit.org/show_bug.cgi?id=26750 + + Inherits RegExpObjectData struct from FastAllocBase because + it has been instantiated by 'new' in JavaScriptCore/runtime/RegExpObject.cpp:62 + + * runtime/RegExpObject.h: + +2009-08-06 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Darin Adler. + + Updated patch for bug #27059: + Symbian platform always uses little endian encoding, + regardless of compiler. + We need to make sure that we correctly detect EABI architecture + for armv5 targets on Symbian, + where __EABI__ is set but not __ARM_EABI__ + + * wtf/Platform.h: + +2009-08-06 Adam Barth <abarth@webkit.org> + + Unreviewed revert. + + http://bugs.webkit.org/show_bug.cgi?id=27879 + + Revert 46877 because it broke GTK. + + * wtf/Noncopyable.h: + +2009-08-06 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Make get_by_id/put_by_id/method_check/call defer optimization using a data flag rather than a code modification. + ( https://bugs.webkit.org/show_bug.cgi?id=27635 ) + + This improves performance of ENABLE(ASSEMBLER_WX_EXCLUSIVE) builds by 2-2.5%, reducing the overhead to about 2.5%. + (No performance impact with ASSEMBLER_WX_EXCLUSIVE disabled). + + * bytecode/CodeBlock.cpp: + (JSC::printStructureStubInfo): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * bytecode/CodeBlock.h: + (JSC::): + (JSC::CallLinkInfo::seenOnce): + (JSC::CallLinkInfo::setSeen): + (JSC::MethodCallLinkInfo::seenOnce): + (JSC::MethodCallLinkInfo::setSeen): + - Change a pointer in CallLinkInfo/MethodCallLinkInfo to use a PtrAndFlags, use a flag to track when an op has been executed once. + + * bytecode/StructureStubInfo.cpp: + (JSC::StructureStubInfo::deref): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * bytecode/StructureStubInfo.h: + (JSC::StructureStubInfo::StructureStubInfo): + (JSC::StructureStubInfo::initGetByIdSelf): + (JSC::StructureStubInfo::initGetByIdProto): + (JSC::StructureStubInfo::initGetByIdChain): + (JSC::StructureStubInfo::initGetByIdSelfList): + (JSC::StructureStubInfo::initGetByIdProtoList): + (JSC::StructureStubInfo::initPutByIdTransition): + (JSC::StructureStubInfo::initPutByIdReplace): + (JSC::StructureStubInfo::seenOnce): + (JSC::StructureStubInfo::setSeen): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID, add a flag to track when an op has been executed once. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetById): + (JSC::BytecodeGenerator::emitPutById): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::unlinkCall): + - Remove the "don't lazy link" stage of calls. + + * jit/JIT.h: + (JSC::JIT::compileCTIMachineTrampolines): + - Remove the "don't lazy link" stage of calls. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallSlowCase): + - Remove the "don't lazy link" stage of calls. + + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::JITStubs::DEFINE_STUB_FUNCTION): + (JSC::JITStubs::getPolymorphicAccessStructureListSlot): + - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check. + + * jit/JITStubs.h: + (JSC::JITThunks::ctiStringLengthTrampoline): + (JSC::JITStubs::): + - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check. + + * wtf/PtrAndFlags.h: + (WTF::PtrAndFlags::PtrAndFlags): + (WTF::PtrAndFlags::operator!): + (WTF::PtrAndFlags::operator->): + - Add ! and -> operators, add constuctor with pointer argument. + +2009-08-06 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Adam Barth. + + Allow custom memory allocation control for Noncopyable class + https://bugs.webkit.org/show_bug.cgi?id=27879 + + Several classes which inherited from Noncopyable are instantiated by + operator new, so Noncopyable class has been inherited from FastAllocBase. + + * wtf/Noncopyable.h: + +2009-08-06 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Sam Weinig. + + Add explicit dependencies for our build verification scripts to ensure that they always run after linking has completed. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-08-06 Mark Rowe <mrowe@apple.com> + + Bring a little order to our otherwise out of control lives. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-08-06 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's PolymorphicAccessStructureList struct + https://bugs.webkit.org/show_bug.cgi?id=27877 + + Inherits PolymorphicAccessStructureList struct from FastAllocBase because it has been instantiated by + 'new' in JavaScriptCore/jit/JITStubs.cpp:1229. + + * bytecode/Instruction.h: + +2009-08-05 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's ScopeNodeData struct + https://bugs.webkit.org/show_bug.cgi?id=27875 + + Inherits ScopeNodeData struct from FastAllocBase because it has been instantiated by + 'new' in JavaScriptCore/parser/Nodes.cpp:1848. + + * parser/Nodes.h: + +2009-08-05 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Add floating point support for generic ARM port. + https://bugs.webkit.org/show_bug.cgi?id=24986 + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::doubleTransfer): + * assembler/ARMAssembler.h: + (JSC::ARM::): + (JSC::ARMAssembler::): + (JSC::ARMAssembler::faddd_r): + (JSC::ARMAssembler::fsubd_r): + (JSC::ARMAssembler::fmuld_r): + (JSC::ARMAssembler::fcmpd_r): + (JSC::ARMAssembler::fdtr_u): + (JSC::ARMAssembler::fdtr_d): + (JSC::ARMAssembler::fmsr_r): + (JSC::ARMAssembler::fsitod_r): + (JSC::ARMAssembler::fmstat): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::): + (JSC::MacroAssemblerARM::supportsFloatingPoint): + (JSC::MacroAssemblerARM::loadDouble): + (JSC::MacroAssemblerARM::storeDouble): + (JSC::MacroAssemblerARM::addDouble): + (JSC::MacroAssemblerARM::subDouble): + (JSC::MacroAssemblerARM::mulDouble): + (JSC::MacroAssemblerARM::convertInt32ToDouble): + (JSC::MacroAssemblerARM::branchDouble): + * jit/JIT.h: + +2009-08-05 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Add JIT support for generic ARM port without optimizations. + https://bugs.webkit.org/show_bug.cgi?id=24986 + + All JIT optimizations are disabled. + + Signed off by Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + Signed off by Gabor Loki <loki@inf.u-szeged.hu> + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::baseIndexTransfer32): + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::Imm32::Imm32): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::store32): + (JSC::MacroAssemblerARM::move): + (JSC::MacroAssemblerARM::branch32): + (JSC::MacroAssemblerARM::add32): + (JSC::MacroAssemblerARM::sub32): + (JSC::MacroAssemblerARM::load32): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::getBytecodeIndex): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::restoreArgumentReference): + * jit/JITOpcodes.cpp: + * jit/JITStubs.cpp: + * jit/JITStubs.h: + (JSC::JITStackFrame::returnAddressSlot): + * wtf/Platform.h: + +2009-08-04 Gavin Barraclough <barraclough@apple.com> + + Rubber Stamped by Oiver Hunt. + + Revert r46643 since this breaks the Yarr::Interpreter running the v8 tests. + https://bugs.webkit.org/show_bug.cgi?id=27874 + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::Interpreter::allocDisjunctionContext): + (JSC::Yarr::Interpreter::freeDisjunctionContext): + (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext): + (JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext): + +2009-08-04 Oliver Hunt <oliver@apple.com> + + PPC64 Build fix + + * wtf/Platform.h: + +2009-08-04 Benjamin C Meyer <benjamin.meyer@torchmobile.com> + + Reviewed by Adam Treat + + Explicitly include limits.h header when using INT_MAX and INT_MIN + + * interpreter/Interpreter.cpp + +2009-08-03 Harald Fernengel <harald.fernengel@nokia.com> + + Reviewed by Darin Adler. + + Fix compile error for ambigous call to abs() + https://bugs.webkit.org/show_bug.cgi?id=27873 + + Fix ambiguity in abs(long int) call by calling labs() instead + + * wtf/DateMath.cpp: replace call to abs() with labs() + +2009-08-03 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Consolidate common gcc flags to WebKit.pri + https://bugs.webkit.org/show_bug.cgi?id=27934 + + * JavaScriptCore.pro: + +2009-08-03 Ada Chan <adachan@apple.com> + + Fixed the Tiger build. + + * wtf/FastMalloc.cpp: + +2009-08-03 Ada Chan <adachan@apple.com> + + Reviewed by Darin Adler. + + Don't use background thread to scavenge memory on Tiger until we figure out why it causes a crash. + https://bugs.webkit.org/show_bug.cgi?id=27900 + + * wtf/FastMalloc.cpp: + +2009-08-03 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Jan Alonzo. + + Fix build break on Gtk/x86_64. + https://bugs.webkit.org/show_bug.cgi?id=27936 + + Use JSVALUE64 for X86_64 LINUX, except Qt. + + * wtf/Platform.h: + +2009-08-02 Xan Lopez <xlopez@igalia.com> + + Fix the GTK+ build. + + * wtf/Platform.h: + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Disabled JSVALUE32_64 on Qt builds, since all layout tests mysteriously + crash with it enabled. + + * wtf/Platform.h: + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Qt build fix. + + Added JSAPIValueWrapper.cpp to the build. + + * JavaScriptCore.pri: + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Windows build fix. + + Exported symbols for JSAPIValueWrapper. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + GTK build fix. + + * jit/JITStubs.cpp: #include <stdarg.h>, for a definition of va_start. + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Qt build fix. + + * runtime/Collector.cpp: #include <limits.h>, for a definition of ULONG_MAX. + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Nixed JSImmediate::prototype, JSImmediate::toObject, + and JSImmediate::toThisObject, and removed their exported symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + * runtime/JSImmediate.cpp: + * runtime/JSImmediate.h: + +2009-08-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Mark Rowe. + + Enabled JSVALUE32_64 by default on all platforms other than x86_64 (which uses JSVALUE64). + + * wtf/Platform.h: + +2009-08-02 Kevin Ollivier <kevino@theolliviers.com> + + Reviewed by Jan Alonzo. + + Script for building the JavaScriptCore library for wx. + https://bugs.webkit.org/show_bug.cgi?id=27619 + + * wscript: Added. + +2009-08-02 Yong Li <yong.li@torchmobile.com> + + Reviewed by George Staikos. + + DateMath depends on strftime and localtime, which need to be imported manually on WinCE + https://bugs.webkit.org/show_bug.cgi?id=26558 + + * wtf/DateMath.cpp: + +2009-08-01 David Kilzer <ddkilzer@apple.com> + + wtf/Threading.h: added include of Platform.h + + Reviewed by Mark Rowe. + + * wtf/Threading.h: Added #include "Platform.h" since this header + uses PLATFORM() and other macros. + +2009-08-01 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Oliver Hunt. + + Roll out r46668 as it was misinformed. ScopeChain is only used with placement new. + + * runtime/ScopeChain.h: + +2009-08-01 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Allow custom memory allocation control for JavaScriptCore's HashMap class + http://bugs.webkit.org/show_bug.cgi?id=27871 + + Inherits HashMap class from FastAllocBase because it has been + instantiated by 'new' in JavaScriptCore/API/JSClassRef.cpp:148. + + * wtf/RefPtrHashMap.h: + (WTF::): + +2009-08-01 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Allow custom memory allocation control for JavaScriptCore's ScopeChain class + https://bugs.webkit.org/show_bug.cgi?id=27834 + + Inherits ScopeChain class from FastAllocBase because it has been + instantiated by 'new' in JavaScriptCore/runtime/JSFunction.h:109. + + * runtime/ScopeChain.h: + +2009-08-01 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's RegExpConstructorPrivate struct + https://bugs.webkit.org/show_bug.cgi?id=27833 + + Inherits RegExpConstructorPrivate class from FastAllocBase because it has been + instantiated by 'new' in JavaScriptCore/runtime/RegExpConstructor.cpp:152. + + * runtime/RegExpConstructor.cpp: + +2009-07-31 Yong Li <yong.li@torchmobile.com> + + Reviewed by George Staikos. + + Resurrect the old GetTickCount implementation of currentTime, controlled by WTF_USE_QUERY_PERFORMANCE_COUNTER + currentSystemTime taken from older WebKit; currentTime written by Yong Li <yong.li@torchmobile.com>; cleanup by Joe Mason <joe.mason@torchmobile.com> + https://bugs.webkit.org/show_bug.cgi?id=27848 + + * wtf/CurrentTime.cpp: + (WTF::currentSystemTime): get current time with GetCurrentFT + (WTF::currentTime): track msec elapsed since first currentSystemTime call using GetTickCount + * wtf/Platform.h: + +2009-07-31 Ada Chan <adachan@apple.com> + + Fixes the Windows release-PGO build. + + Reviewed by Jon Honeycutt. + + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Suppresses the warning about unreachable code that we get by adding "return 0" to WTF::TCMalloc_PageHeap::runScavengerThread(). + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_PageHeap::runScavengerThread): Fixes the error about the method not returning a value in the release-PGO build. + +2009-07-31 Zoltan Horvath <hzoltan@inf.u-szeged.hu> + + Change malloc to fastMalloc and free to fastFree in Yarr's RegexInterpreter.cpp + https://bugs.webkit.org/show_bug.cgi?id=27874 + + Use fastMalloc and fastFree instead of malloc and free in RegexInterpreter.cpp's methods. + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::Interpreter::allocDisjunctionContext): + (JSC::Yarr::Interpreter::freeDisjunctionContext): + (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext): + (JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext): + +2009-07-30 Xan Lopez <xlopez@igalia.com> + + Reviewed by Jan Alonzo. + + Fix compiler warning. + + GCC does not like C++-style comments in preprocessor directives. + + * wtf/Platform.h: + +2009-07-30 John McCall <rjmccall@apple.com> + + Reviewed by Gavin Barraclough. + + Optimize the X86_64 trampolines: avoid the need for filler arguments + and move the stub-args area closer to the stack pointer. + + * jit/JIT.h: adjust patch offsets because of slight code-size change + * jit/JITCode.h: + (JSC::JITCode::execute): don't pass filler args + * jit/JITStubs.cpp: + (ctiTrampoline): (X86_64): push args onto stack, use args directly + (ctiVMThrowTrampoline): (X86_64): adjust %rsp by correct displacement + (ctiOpThrowNotCaught): (X86_64): adjust %rsp by correct displacement + * jit/JITStubs.h: + (JITStackFrame): (X86_64): move args area earlier + (ctiTrampoline): remove filler args from prototype + +2009-07-30 Gavin Barraclough <barraclough@apple.com> + + Temporarily revert r46618 since this is b0rking on Linux. + +2009-07-23 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + Make get_by_id/put_by_id/method_check/call defer optimization using a data flag rather than a code modification. + ( https://bugs.webkit.org/show_bug.cgi?id=27635 ) + + This improves performance of ENABLE(ASSEMBLER_WX_EXCLUSIVE) builds by 2-2.5%, reducing the overhead to about 2.5%. + (No performance impact with ASSEMBLER_WX_EXCLUSIVE disabled). + + * bytecode/CodeBlock.cpp: + (JSC::printStructureStubInfo): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * bytecode/CodeBlock.h: + (JSC::): + (JSC::CallLinkInfo::seenOnce): + (JSC::CallLinkInfo::setSeen): + (JSC::MethodCallLinkInfo::seenOnce): + (JSC::MethodCallLinkInfo::setSeen): + - Change a pointer in CallLinkInfo/MethodCallLinkInfo to use a PtrAndFlags, use a flag to track when an op has been executed once. + + * bytecode/StructureStubInfo.cpp: + (JSC::StructureStubInfo::deref): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * bytecode/StructureStubInfo.h: + (JSC::StructureStubInfo::StructureStubInfo): + (JSC::StructureStubInfo::initGetByIdSelf): + (JSC::StructureStubInfo::initGetByIdProto): + (JSC::StructureStubInfo::initGetByIdChain): + (JSC::StructureStubInfo::initGetByIdSelfList): + (JSC::StructureStubInfo::initGetByIdProtoList): + (JSC::StructureStubInfo::initPutByIdTransition): + (JSC::StructureStubInfo::initPutByIdReplace): + (JSC::StructureStubInfo::seenOnce): + (JSC::StructureStubInfo::setSeen): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID, add a flag to track when an op has been executed once. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetById): + (JSC::BytecodeGenerator::emitPutById): + - Make StructureStubInfo store the type as an integer, rather than an OpcodeID. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::unlinkCall): + - Remove the "don't lazy link" stage of calls. + + * jit/JIT.h: + (JSC::JIT::compileCTIMachineTrampolines): + - Remove the "don't lazy link" stage of calls. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallSlowCase): + - Remove the "don't lazy link" stage of calls. + + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::JITStubs::DEFINE_STUB_FUNCTION): + (JSC::JITStubs::getPolymorphicAccessStructureListSlot): + - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check. + + * jit/JITStubs.h: + (JSC::JITThunks::ctiStringLengthTrampoline): + (JSC::JITStubs::): + - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check. + + * wtf/PtrAndFlags.h: + (WTF::PtrAndFlags::PtrAndFlags): + (WTF::PtrAndFlags::operator!): + (WTF::PtrAndFlags::operator->): + - Add ! and -> operators, add constuctor with pointer argument. + +2009-07-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Gavin Barraclough. + + Fixed failing tests seen on Windows buildbot. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): Use "int" instead of "bool" to guarantee a 32-bit result, + regardless of compiler. gcc on mac uses 32-bit values for bool, + but gcc on linux and MSVC on Windows use 8-bit values. + +2009-07-30 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: added missing symbols on Windows. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-07-30 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: removed stale symbols on Windows. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +=== End merge of nitro-extreme branch 2009-07-30 === + +2009-07-20 Geoffrey Garen <ggaren@apple.com> + + Fixed a post-review typo in r46066 that caused tons of test failures. + + SunSpider reports no change. + + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): Initialize the full vector capacity, to avoid + uninitialized members at the end. + +2009-07-20 Geoffrey Garen <ggaren@apple.com> + + Windows WebKit build fix: Added some missing exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-07-17 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Get the branch working on windows. + https://bugs.webkit.org/show_bug.cgi?id=27391 + + SunSpider says 0.3% faster. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Updated + MSVC export lists to fix linker errors. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Added / removed + new / old project files. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): Used #pragma pack to tell + MSVC that these structures represent actual memory layout, and should not be + automatically aligned. Changed the return value load to load a 64bit quantity + into the canonical registers. + + * jit/JIT.h: Moved OBJECT_OFFSETOF definition to StdLibExtras.h because + it's needed by more than just the JIT, and it supplements a standard library + macro (offsetof). + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallInitializeCallFrame): Fixed an incorrectly signed + cast to resolve an MSVC warning. + + * jit/JITStubs.h: Used #pragma pack to tell MSVC that these structures + represent actual memory layout, and should not be automatically aligned. + + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): Replaced memset_pattern8 with a for loop, since + memset_pattern8 is not portable. (I verified that this version of the loop + gives the best performance / generated code in GCC.) + + * runtime/JSObject.h: + (JSC::JSObject::JSObject): Removed accidental usage of FIELD_OFFSET -- + OBJECT_OFFSETOF is our new macro name. (FIELD_OFFSET conflicts with a + definition in winnt.h.) + + * runtime/JSValue.cpp: Added some headers needed by non-all-in-one builds. + + * runtime/JSValue.h: + (JSC::JSValue::): Made the tag signed, to match MSVC's signed enum values. + (GCC doesn't seem to care one way or the other.) + + * wtf/MainThread.cpp: Moved the StdLibExtras.h #include -- I did this a + while ago to resolve a conflict with winnt.h. I can't remember if it's truly + still needed, but what the heck. + + * wtf/StdLibExtras.h: Moved OBJECT_OFFSETOF definition here. + +2009-07-06 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig (?). + + Fixed an assertion seen during the stress test. + + Don't assume that, if op1 is constant, op2 is not, and vice versa. Sadly, + not all constants get folded. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + +2009-07-06 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Include op_convert_this in result caching. + + No change on SunSpider or v8. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_convert_this): + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): Made the op_convert_this JIT stub return an EncodedJSValue, so + to maintain the result caching contract that { tag, payload } can be + found in { regT1, regT0 }. + +2009-07-06 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented result chaining. + + 1% faster on SunSpider. 4%-5% faster on v8. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::move): + * assembler/X86Assembler.h: + (JSC::X86Assembler::movl_rr): Added an optimization to eliminate + no-op mov instructions, to simplify chaining. + + * jit/JIT.cpp: + (JSC::JIT::JIT): + * jit/JIT.h: Added data members and helper functions for recording + chained results. We record both a mapping from virtual to machine register + and the opcode for which the mapping is valid, to help ensure that the + mapping isn't used after the mapped register has been stomped by other + instructions. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::compileOpCallVarargsSlowCase): + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_construct_verify): + (JSC::JIT::compileOpCall): + (JSC::JIT::compileOpCallSlowCase): Chain function call results. + + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoadTag): + (JSC::JIT::emitLoadPayload): + (JSC::JIT::emitLoad): + (JSC::JIT::emitLoad2): + (JSC::JIT::isLabeled): + (JSC::JIT::map): + (JSC::JIT::unmap): + (JSC::JIT::isMapped): + (JSC::JIT::getMappedPayload): + (JSC::JIT::getMappedTag): Use helper functions when loading virtual + registers into machine registers, in case the loads can be eliminated + by chaining. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_mov): + (JSC::JIT::emit_op_end): + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_next_pname): + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emit_op_catch): Chain results from these opcodes. + + (JSC::JIT::emit_op_profile_will_call): + (JSC::JIT::emit_op_profile_did_call): Load the profiler into regT2 to + avoid stomping a chained result. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_get_by_id): Chain results from these opcodes. + + * jit/JITStubCall.h: + (JSC::JITStubCall::addArgument): Always use { regT1, regT0 }, to facilitate + chaining. + + (JSC::JITStubCall::call): Unmap all mapped registers, since our callee + stub might stomp them. + +2009-07-01 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Don't reload values in emitBinaryDoubleOp. + + SunSpider reports a 0.6% progression. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitBinaryDoubleOp): + +2009-07-01 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Convert op_div to load op1 and op2 up front. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_div): + +2009-07-01 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Don't emit code in emitBinaryDoubleOp if code is unreachable, observable + via an empty (unlinked) jumplist passed in. This only effects op_jnless + and op_jnlesseq at present. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emitSlow_op_jnlesseq): + (JSC::JIT::emitBinaryDoubleOp): + +2009-07-01 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Converted op_mod to put { tag, payload } in { regT1, regT0 }, and + tidied up its constant case. + + SunSpider reports a 0.2% regression, but a micro-benchmark of op_mod + shows a 12% speedup, and the SunSpider test that uses op_mod most should + benefit a lot from result caching in the end, since it almost always + performs (expression) % constant. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + +2009-06-30 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Converted some more arithmetic ops to put { tag, payload } in + { regT1, regT0 }. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Converted some more arithmetic ops to put { tag, payload } in + { regT1, regT0 }, and added a case for subtract constant. + + SunSpider says no change. v8 says 0.3% slower. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_add): + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSub32Constant): + (JSC::JIT::emitSlow_op_sub): + +2009-06-30 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Remove more uses of addressFor(), load double constants directly from + the constantpool in the CodeBlock, rather than from the register file. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitBinaryDoubleOp): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed a bug in postfix ops, where we would treat x = x++ and x = x-- + as a no-op, even if x were not an int, and the ++/-- could have side-effects. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emitSlow_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emitSlow_op_post_dec): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Converted some arithmetic ops to put { tag, payload } in + { regT1, regT0 }. + + SunSpider says 0.7% faster. v8 says no change. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emit_op_lshift): + (JSC::JIT::emit_op_rshift): + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emit_op_bitxor): + * jit/JITInlineMethods.h: + (JSC::JIT::isOperandConstantImmediateInt): + (JSC::JIT::getOperandConstantImmediateInt): + +2009-06-30 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Start removing cases of addressFor(). + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_div): + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoadDouble): + (JSC::JIT::emitLoadInt32ToDouble): + (JSC::JIT::emitStoreDouble): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jtrue): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Rolled back in my last patch with regression fixed. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emitSlow_op_resolve_global): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Rolled out my last patch because it was a 2% SunSpider regression. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Gavin "Sam Weinig" Barraclough. + + Standardized the rest of our opcodes to put { tag, payload } in + { regT1, regT0 } where possible. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emitSlow_op_resolve_global): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + +2009-06-30 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Geoffrey Garen. + + Replace calls to store32(tagFor()) and store32(payloadFor()) + with emitStoreInt32(), emitStoreBool(), and emitStoreCell(). + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_negate): + (JSC::JIT::emit_op_lshift): + (JSC::JIT::emit_op_rshift): + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emitBitAnd32Constant): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emitBitOr32Constant): + (JSC::JIT::emit_op_bitxor): + (JSC::JIT::emitBitXor32Constant): + (JSC::JIT::emit_op_bitnot): + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emit_op_pre_inc): + (JSC::JIT::emit_op_pre_dec): + (JSC::JIT::emit_op_add): + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSub32ConstantLeft): + (JSC::JIT::emitSub32ConstantRight): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emit_op_div): + (JSC::JIT::emit_op_mod): + * jit/JITCall.cpp: + (JSC::JIT::emit_op_load_varargs): + * jit/JITInlineMethods.h: + (JSC::JIT::emitStoreInt32): + (JSC::JIT::emitStoreCell): + (JSC::JIT::emitStoreBool): + (JSC::JIT::emitStore): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emit_op_not): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + (JSC::JIT::compileOpStrictEq): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITStubCall.h: + (JSC::JITStubCall::call): + +2009-06-30 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized the rest of the property access instructions to put { tag, + payload } in { regT1, regT0 }. + + Small v8 speedup, 0.2% SunSpider slowdown. + + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoad): + (JSC::JIT::emitLoad2): + * 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): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::emitSlow_op_put_by_id): + (JSC::JIT::patchPutByIdReplace): + +2009-06-29 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Various cleanups. + - Use fpRegT* instead of X86::xmm*. + - Use a switch statement in emitBinaryDoubleOp instead of a bunch of + if/elses. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_div): + +2009-06-29 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add inline code dealing with doubles for op_jfalse and op_jtrue. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::): + (JSC::MacroAssemblerX86Common::zeroDouble): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jtrue): + +2009-06-28 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized op_get_by_id to put { tag, payload } in { regT1, regT0 }. + + SunSpider and v8 report maybe 0.2%-0.4% regressions, but the optimization + this enables will win much more than that back. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::emit_op_get_by_id): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compileGetByIdSlowCase): + (JSC::JIT::patchGetByIdSelf): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + +2009-06-26 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + Standardized op_call to put { tag, payload } in { regT1, regT0 }. + + SunSpider and v8 report no change. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallInitializeCallFrame): + (JSC::JIT::compileOpCallSetupArgs): + (JSC::JIT::compileOpConstructSetupArgs): + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::compileOpCall): + (JSC::JIT::compileOpCallSlowCase): + +2009-06-26 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Handle multiplying by zero a little better by + inlining the case that both operands are non-negative + into the slowpath. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::branchOr32): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Optimize x++ to ++x inside for loops. + + Sadly, no measurable speedup, but this should help with result chaining. + + * parser/Nodes.cpp: + (JSC::ForNode::emitBytecode): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized some more opcodes to put { tag, payload } in { regT1, regT0 }. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_bitnot): + (JSC::JIT::emit_op_post_inc): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized some more opcodes to put { tag, payload } in { regT1, regT0 }. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_bitnot): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emit_op_pre_inc): + (JSC::JIT::emitSlow_op_pre_inc): + (JSC::JIT::emit_op_pre_dec): + (JSC::JIT::emitSlow_op_pre_dec): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized some more opcodes to put { tag, payload } in { regT1, regT0 }. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_negate): + (JSC::JIT::emitSlow_op_negate): + * jit/JITCall.cpp: + (JSC::JIT::emit_op_construct_verify): + (JSC::JIT::emitSlow_op_construct_verify): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Standardized some more opcodes to put { tag, payload } in { regT1, regT0 }. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_true): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + +2009-06-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig (sort of, maybe). + + Fixed some ASSERTs in http/tests/security. + + These ASSERTs were introduced by http://trac.webkit.org/changeset/45057, + but the underlying problem was actually older. http://trac.webkit.org/changeset/45057 + just exposed the problem by enabling optimization in more cases. + + The ASSERTs fired because we tested PropertySlot::slotBase() for validity, + but slotBase() ASSERTs if it's invalid, so we would ASSERT before + the test could happen. Solution: Remove the ASSERT. Maybe it was valid + once, but it clearly goes against a pattern we've deployed of late. + + The underlying problem was that WebCore would re-use a PropertySlot in + the case of a forwarding access, and the second use would not completely + overwrite the first use. Solution: Make sure to overwrite m_offset when + setting a value on a PropertySlot. (Other values already get implicitly + overwritten during reuse.) + + * runtime/PropertySlot.h: + (JSC::PropertySlot::PropertySlot): + (JSC::PropertySlot::setValueSlot): + (JSC::PropertySlot::setValue): + (JSC::PropertySlot::setRegisterSlot): + (JSC::PropertySlot::setUndefined): + (JSC::PropertySlot::slotBase): + (JSC::PropertySlot::clearOffset): + +2009-06-24 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Geoff Garen. + + Enable JIT_OPTIMIZE_METHOD_CALLS on the branch, implementation matches current implemenatation in ToT. + + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::emitSlow_op_method_check): + (JSC::JIT::emit_op_get_by_id): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emitSlow_op_get_by_id): + (JSC::JIT::compileGetByIdSlowCase): + +2009-06-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Bit off a tiny bit more of standardizing opcode behavior to help with result + caching. + + SunSpider reports no change, v8 maybe a tiny speedup. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emitSlow_op_to_jsnumber): + (JSC::JIT::emit_op_convert_this): + (JSC::JIT::emitSlow_op_convert_this): + +2009-06-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Bit off a tiny bit more of standardizing opcode behavior to help with result + caching -- including removing my old enemy, op_resolve_function, because + it was non-standard, and removing it felt better than helping it limp along. + + SunSpider reports no change, v8 maybe a tiny speedup. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + * bytecompiler/BytecodeGenerator.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emitSlow_op_to_primitive): + * jit/JITStubs.cpp: + * jit/JITStubs.h: + * parser/Nodes.cpp: + (JSC::FunctionCallResolveNode::emitBytecode): + +2009-06-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Bit off a tiny bit of standardizing opcode behavior to help with result + caching. + + 0.6% SunSpider speedup. 0.3% v8 speedup. + + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoad): Accomodate a base register that overlaps with payload + by loading tag before payload, to avoid stomping base/payload. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_mov): Abide by the standard "tag in regT1, payload in + regT0" semantics. + + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): Ditto. Also, removed some irrelevent + loads while I was at it. The global object's "d" pointer never changes + after construction. + +2009-06-23 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Remove 'arguments' field from Register union (again). + This time do so without breaking tests (radical, I know). + + * interpreter/CallFrame.h: + (JSC::ExecState::optionalCalleeArguments): + (JSC::ExecState::setArgumentCount): + (JSC::ExecState::init): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::dumpRegisters): + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::privateExecute): + (JSC::Interpreter::retrieveArguments): + * interpreter/Register.h: + (JSC::Register::withInt): + (JSC::Register::): + (JSC::Register::Register): + (JSC::Register::i): + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_tear_off_arguments): + * runtime/Arguments.h: + (JSC::JSActivation::copyRegisters): + (JSC::Register::arguments): + * runtime/JSActivation.cpp: + (JSC::JSActivation::argumentsGetter): + * runtime/JSActivation.h: + +2009-06-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Removed some result register tracking cruft in preparation for a new + result tracking mechanism. + + SunSpider reports no change. + + * assembler/AbstractMacroAssembler.h: + * assembler/X86Assembler.h: + (JSC::X86Assembler::JmpDst::JmpDst): No need to track jump targets in + machine code; we already do this in bytecode. + + * jit/JIT.cpp: + (JSC::JIT::JIT): + (JSC::JIT::emitTimeoutCheck): Make sure to save and restore the result + registers, so an opcode with a timeout check can still benefit from result + register caching. + + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): Removed calls to killLastResultRegister() + in preparation for something new. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + * jit/JITInlineMethods.h: + (JSC::JIT::emitGetFromCallFrameHeaderPtr): + (JSC::JIT::emitGetFromCallFrameHeader32): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_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_sret): + (JSC::JIT::emit_op_jmp_scopes): ditto + + * jit/JITStubCall.h: + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::getArgument): added a mechanism for reloading an argument + you passed to a JIT stub, for use in emitTimeoutCheck. + +2009-06-23 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Remove now-useless inplace variants of binary ops. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emit_op_bitxor): + (JSC::JIT::emit_op_add): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emit_op_mul): + +2009-06-23 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Move off memory operands to aid in re-enabling result caching. + + - No regression measured. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_negate): + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emit_op_lshift): + (JSC::JIT::emit_op_rshift): + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emitBitAnd32Constant): + (JSC::JIT::emitBitAnd32InPlace): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emitBitOr32Constant): + (JSC::JIT::emitBitOr32InPlace): + (JSC::JIT::emit_op_bitxor): + (JSC::JIT::emitBitXor32Constant): + (JSC::JIT::emitBitXor32InPlace): + (JSC::JIT::emit_op_bitnot): + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emit_op_pre_inc): + (JSC::JIT::emitSlow_op_pre_inc): + (JSC::JIT::emit_op_pre_dec): + (JSC::JIT::emitSlow_op_pre_dec): + (JSC::JIT::emit_op_add): + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitAdd32InPlace): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlowAdd32Constant): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSlow_op_sub): + (JSC::JIT::emitSub32ConstantLeft): + (JSC::JIT::emitSub32ConstantRight): + (JSC::JIT::emitSub32InPlaceLeft): + (JSC::JIT::emitSub32InPlaceRight): + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitMul32InPlace): + (JSC::JIT::emit_op_div): + (JSC::JIT::emit_op_mod): + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargs): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emit_op_not): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emit_op_to_jsnumber): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + +2009-06-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed some missing and/or misplaced labels in bytecode generation, so + we don't have to work around them in JIT code generation. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitJumpSubroutine): + * parser/Nodes.cpp: + (JSC::TryNode::emitBytecode): + +2009-06-22 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + For member function calls, emit "this" directly into the "this" slot + for the function call, instead of moving it there later. This reduces + time spent in op_mov during certain calls, like "a.b.c()". + + 1%-2% speedup on v8, mostly richards and delta-blue. + + * parser/Nodes.cpp: + (JSC::FunctionCallDotNode::emitBytecode): + +2009-06-22 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Remove 'arguments' field from Register union. Having JSCell derived types in the union is + dangerous since it opens the possibility for the field to be written as a raw pointer but + then read as a JSValue. This will lead to statle data being read for the tag, which may + be dangerous. Having removed Arguments* types form Register, all arguments objects must + always explicitly be stored in the register file as JSValues. + + * interpreter/CallFrame.h: + (JSC::ExecState::optionalCalleeArguments): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::privateExecute): + (JSC::Interpreter::retrieveArguments): + * interpreter/Register.h: + (JSC::Register::): + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_tear_off_arguments): + * runtime/Arguments.h: + (JSC::JSActivation::copyRegisters): + * runtime/JSActivation.cpp: + (JSC::JSActivation::argumentsGetter): + * runtime/JSActivation.h: + +2009-06-03 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add back known this value optimization by abstracting + slow case if not JSCell jumps. + + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::compileOpCallVarargsSlowCase): + (JSC::JIT::compileOpCall): + (JSC::JIT::compileOpCallSlowCase): + * jit/JITInlineMethods.h: + (JSC::JIT::emitJumpSlowCaseIfNotJSCell): + (JSC::JIT::linkSlowCaseIfNotJSCell): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): + * 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): + (JSC::JIT::emit_op_get_by_id): + (JSC::JIT::emitSlow_op_get_by_id): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::emitSlow_op_put_by_id): + +2009-06-01 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed some of the regression in crypto-aes.js. (8.5% speedup in + crypto-aes.js.) + + SunSpider reports no change overall. + + Division was producing double results, which took the slow path through + array access code. + + Strangely, all my attempts at versions of this patch that modified array + access code to accept ints encoded as doubles along the fast or slow paths + were regressions. So I did this instead. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_div): When dividing an int by an int, go ahead and try + to turn the result into an int. Don't just do int division, though, because + testing shows it to be slower than SSE double division, and the corner + cases are pretty complicated / lengthy on top of that. Also, don't try + to canonicalize division of known tiny numerators into ints, since that's a + waste of time. + +2009-05-26 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fixed a regression caused by my recent fix for NaN. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitBinaryDoubleOp): Actually do the comparison in reverse + order, like the ChangeLog said we would, bokay? + +2009-05-26 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig and Oliver Hunt. + + Fixed two edge cases in %: + + - Don't do -2147483648 % x as a fast case, since you might do -2147483648 % -1, + which will signal a hardware exception due to overflow. + + - In the case of a zero remainder, be sure to store negative zero if the + dividend was zero. + + SunSpider reports no change. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + +2009-05-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + Fixed a regression when comparing to NaN. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitBinaryDoubleOp): For op_jnless and op_jnless_eq, do the + comparison in reverse order, and jump if the result is below or + below-or-equal. This ensures that we do jump in the case of NaN. + +2009-05-25 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + SunSpider says no change. + + Fixed regressions in fast/js/var-declarations-shadowing.html and + fast/js/equality.html, caused by recent == and != optimizations. + + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_eq): Don't treat "compare to string" as always + numeric or string comparison. If the second operand is an object, you + need to ToPrimitive it, and start all over again. Also, I wrote out each + of the possible cases explicitly, to cut down on redundant branching. + +2009-05-25 Sam Weinig <sam@webkit.org> + + Reviewed by Mark Rowe. + + Fix bug in fast/js/constant-folding.html where we were not negating + -0 properly. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_negate): + +2009-05-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Refactored new slow case codegen for == and !=. + + SunSpider reports no change, maybe a tiny speedup. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emitSlow_op_neq): Made a vptr comparison a *Ptr operation, + instead of *32, to make it portable to 64bit. Reorganized the string + and generic cases to make their control flow a little clearer. + +2009-05-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + Optimized == and != for our new value representation -- especially for strings. + + 14% speedup on date-format-tofte. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + * jit/JITStubCall.h: + (JSC::JITStubCall::JITStubCall): + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_eq): + (JSC::JITStubs::cti_op_eq_strings): + (JSC::JITStubs::cti_op_call_eval): + * jit/JITStubs.h: + (JSC::): + * runtime/JSValue.h: + +2009-05-22 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Fix non-SSE enabled builds. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_add): Don't early return here, we still need to call the JIT stub. + (JSC::JIT::emitSlow_op_sub): Ditto. + +2009-05-22 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Here's a thought: let's not take a jit stub call just to multiply by 1, + bokay? + + imul doesn't set the zero flag, so to test for a zero result, we need + an explicit instruction. (Luckily, it does set the overflow flag, so + we can still use that.) + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emitMul32InPlace): + +2009-05-22 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey "Premature Commit" Garen. + + Add back constant integer cases for op_add. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_add): + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlowAdd32Constant): + * jit/JITInlineMethods.h: + (JSC::JIT::getConstantOperandImmediateDouble): + (JSC::JIT::isOperandConstantImmediateDouble): + +2009-05-22 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added fast double cases for op_jnless and op_jnlesseq. + + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::JumpList::jumps): New accesor, used by + addSlowCase. + + * assembler/X86Assembler.h: + (JSC::X86Assembler::ucomisd_rm): New method for comparing register to + memory. + + * jit/JIT.h: + * 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::emit_op_add): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emit_op_div): Modified emitBinaryDoubleOp to accept comparison/jump + operations in addition to operations with explicit result registers. + + * jit/JITInlineMethods.h: + (JSC::JIT::addSlowCase): Added an "addSlowCase" for JumpLists, so clients + can track multiple jumps to the same slow case condition together. + +2009-05-21 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Implement op_negate inline fast cases. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::neg32): + * assembler/X86Assembler.h: + (JSC::X86Assembler::): + (JSC::X86Assembler::negl_m): + (JSC::X86Assembler::xorpd_rr): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_negate): + (JSC::JIT::emitSlow_op_negate): + +2009-05-20 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Update the patchOffsetGetByIdSlowCaseCall constant for the + case that OPCODE_SAMPLING is enabled. + + * jit/JIT.h: + +2009-05-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added support for inline subtraction of doubles. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSlow_op_sub): + (JSC::JIT::emitSlowSub32InPlaceLeft): + (JSC::JIT::emitBinaryDoubleOp): + +2009-05-20 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Added support for inline division. + + * assembler/X86Assembler.h: + (JSC::X86Assembler::): + (JSC::X86Assembler::divsd_rr): + (JSC::X86Assembler::divsd_mr): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitBinaryOp): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_div): + (JSC::JIT::emitSlow_op_div): + +2009-05-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added support for inline addition of doubles. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_add): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlowAdd32InPlace): + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + +2009-05-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Factored inline double operations into a helper function, so that we + can reuse this code for other math operations. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emitBinaryDoubleOp): + (JSC::JIT::emit_op_mul): + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallInitializeCallFrame): + +2009-05-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added support for inline multiplication of doubles. + + * assembler/X86Assembler.h: + (JSC::X86Assembler::cvtsi2sd_mr): New function, useful for loading an + int32 into a double register. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): Filled out these cases for double arithmetic. + + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::addressFor): New function, useful for addressing a JSValue's + full 64bits as a double. + +2009-05-19 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement and enable optimized calls. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): Add ENABLE(JIT_OPTIMIZE_CALL) guards + around the the optimize call only trampolines (virtualCallPreLink and virtualCallLink). + Update the trampolines to account for the new JSValue representation. + (JSC::JIT::unlinkCall): Use NULL instead of JSValue noValue. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): Update to account for the new JSValue representation + (JSC::JIT::compileOpCallSlowCase): Ditto. + + * jit/JITStubs.h: Remove incorrect !ENABLE(JIT_OPTIMIZE_CALL) guard. + + * wtf/Platform.h: Enable ENABLE_JIT_OPTIMIZE_CALL. + +2009-05-19 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement and enable optimized property access. + + * assembler/AbstractMacroAssembler.h: Fix comment. + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): Remove array length trampoline + and implement the string length trampoline. + * jit/JIT.h: Add new constants for patch offsets. + * jit/JITInlineMethods.h: Remove FIELD_OFFSET which is now in StdLibExtras.h. + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_id): + (JSC::JIT::emitSlow_op_get_by_id): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::emitSlow_op_put_by_id): + (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::patchGetByIdSelf): + (JSC::JIT::patchPutByIdReplace): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITStubCall.h: + (JSC::JITStubCall::addArgument): Add version of addArgument that takes + two registers for the tag and payload. + * jit/JITStubs.cpp: + (JSC::JITStubs::JITStubs): Remove array length trampoline pointer. + (JSC::JITStubs::cti_op_get_by_id_self_fail): + * jit/JITStubs.h: + * runtime/JSObject.h: + (JSC::JSObject::JSObject): Move m_inheritorID below the property storage + to align it to a 16 byte boundary. + * wtf/Platform.h: Enable ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS + * wtf/StdLibExtras.h: Move FIELD_OFFSET here. + +2009-05-17 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Remove unneeded ExecState parameter from the number JSValue constructors. + + * runtime/JSValue.h: + (JSC::jsNumber): + (JSC::jsNaN): + (JSC::JSValue::JSValue): + +2009-05-15 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implemented fast path for op_put_by_val when putting to arrays. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + +2009-05-15 Geoffrey Garen <ggaren@apple.com> (Mostly by Sam) + + Reviewed by Sam Weinig. + + Implemented fast path for op_get_by_val when accessing array. + + * jit/JIT.cpp: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitSlow_op_get_by_val): + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed a failure in fast/js/math-transforms.html caused by failing to + preserve -0 in multiplication. + + * assembler/X86Assembler.h: + (JSC::X86Assembler::jz): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emitMul32Constant): + (JSC::JIT::emitMul32InPlace): Check both for overflow and for zero when + doing multiplication. Use a slow case to get these right. + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed a bug in the varargs calling convention. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargs): Move the argument count into regT1, + since that's where ctiVirtualCall expects it to be. + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed a small bug in instanceof's looping code. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): NULL means the object has no prototype, + so only loop when *not* equal to NULL. + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed a small bug in instanceof's result writing code. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): Make sure to fill out the payload bits + in all cases. + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Removed an invalid assertion in cti_op_urshift which + depended on a fast path for op_urshift which has + never existed. + + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_urshift): + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed loop_if_true, which had the same reversed test that jtrue had. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_true): + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + In op_neq, we apparently want to check that one value + does *not* equal another. Go figure. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_neq): + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + The slow case of op_mod should call op_mod's jit stub, + not op_mul. That would be dumb. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_mod): + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed problems when using 'arguments' due to a half-initialized register. + + * interpreter/CallFrame.h: + (JSC::ExecState::setCalleeArguments): + (JSC::ExecState::init): Require a full JSValue when setting up the + 'arguments' virtual register, since this register is accessible from JIT + code and bytecode, and needs to be a true JSValue. + + * interpreter/CallFrameClosure.h: + (JSC::CallFrameClosure::resetCallFrame): ditto + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): ditto + + * interpreter/Register.h: Removed the constructor that allowed assignment + of a JSArguments* to a register. That is not safe. See above. + + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_create_arguments): + (JSC::JITStubs::cti_op_create_arguments_no_params): ditto + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + We really want to go to the slow case in op_jfalse and + op_jtrue if the value is *not* boolean. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jtrue): + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Flipped the condition when emitting a an op_loop_if_less or op_loop_if_lesseq + if the first operand is a constant. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Added missing return in op_jnless and op_jnlesseq. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + +2009-05-14 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Load constants into the the register file as a temporary measure to + aid bring up. This allows us to use to treat constants like any + other virtual register. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_enter): + (JSC::JIT::emit_op_enter_with_activation): + +2009-05-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented op_strict_eq. Original patch by Snowy, by way of Sam and Gavin. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::set8): Added set8, since it's slightly + faster than set32, and the new value representation usually doesn't + need set32. + + * jit/JIT.cpp: + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoadTag): + (JSC::JIT::emitLoadPayload): Added helper functions for dealing with + constants. Eventually, we should write special cases for all constants, + but these are helpful in the short term. + + * jit/JITOpcodes.cpp: + (JSC::JIT::compileOpStrictEq): + (JSC::JIT::emitSlow_op_stricteq): + (JSC::JIT::emitSlow_op_nstricteq): teh opcodez. + + * runtime/JSValue.h: + (JSC::JSValue::): + (JSC::JSValue::isDouble): Added a LowestTag for clarity. + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fixed some bugs in host function calls. + + testapi now passes! + + * jit/JIT.cpp: Changed some registers around to avoid overwriting edx:eax, + which is how JSValues are now returned. Also changed the code that + passes thisValue to pass the full 64bits of the value. Also added + an #error compiler directive to other platform builds, since the JSValue + return signature probably won't return in edx:eax on those platforms, + and we'll have to investigate a solution. + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Removed parameters from functions that are intended never to use their + parameters. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Ported op_instance_of from TOT. It's basically the same, but some register + stuff changed to memory stuff. + + * jit/JITInlineMethods.h: + (JSC::JIT::emitPutJITStubArgFromVirtualRegister): + (JSC::JIT::emitStore): Changed to use helper functions. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): Ported from TOT. + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Gavin Barraclough. + + Added a comment to explain an exception-handling subtelty that we found + hard to remember when reviewing my last patch. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_catch): + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented try/catch. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_throw): Updated to use JITStackFrame abstraction. + (JSC::JIT::emit_op_catch): Filled out. + +2009-05-13 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implemented op_loop_if_true, op_jfalse, op_jtrue, op_jeq_null and op_jneq_null + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_instanceof): Moved from below to be next to its + fast brother. + + (JSC::JIT::emit_op_loop_if_true): Similar to the old version + in that it tries to do the integer case first and reduce the + number of jumps you might need to take. + (JSC::JIT::emitSlow_op_loop_if_true): + + (JSC::JIT::emit_op_jfalse): Very similar to op_loop_if_true, only + the inverse and without a timeout check. + (JSC::JIT::emitSlow_op_jfalse): + + (JSC::JIT::emit_op_jtrue): Very similar to op_loop_if_true except + without the timeout check. + (JSC::JIT::emitSlow_op_jtrue): + + (JSC::JIT::emit_op_jeq_null): Very similar to the implementation + of op_eq, except it takes jumps instead of copying the condition + to a dst. + (JSC::JIT::emit_op_jneq_null): Ditto but for op_neq. + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented op_call_varargs. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::emit_op_call): + (JSC::JIT::emit_op_call_eval): + (JSC::JIT::emit_op_load_varargs): + (JSC::JIT::emit_op_call_varargs): + (JSC::JIT::emit_op_construct): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jneq_ptr): + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented op_call_eval. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpCall): + * jit/JITStubCall.h: + (JSC::CallEvalJITStub::CallEvalJITStub): + +2009-05-13 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin Barraclough. + + Implemented op_not. (Gavin did most of the work!) + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_not): + (JSC::JIT::emitSlow_op_not): + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Implemented op_global_resolve. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): Added back accidentally removed + early returns. + + (JSC::JIT::emit_op_resolve_global): + * jit/JITStubs.cpp: + (JSC::JITStubs::cti_op_resolve_global): Pretty similar to the old code, + but we need two reads and a TimesEight step in order to account for the + 64bit value size. + + * jit/JITStubs.h: + (JSC::): Slightly tweaked this code to specialize for a JSGlobalObject*, + to avoid having to pass an irrelevant tag pointer to the stub. + +2009-05-13 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implemented op_to_jsnumber. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emitSlow_op_to_jsnumber): + +2009-05-13 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implemented op_convert_this. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_convert_this): + (JSC::JIT::emitSlow_op_convert_this): + +2009-05-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Got basic JS function and constructor calls working. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallSetupArgs): + (JSC::JIT::compileOpCallVarargsSetupArgs): + (JSC::JIT::compileOpConstructSetupArgs): + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_construct_verify): + (JSC::JIT::emitSlow_op_construct_verify): + (JSC::JIT::emitSlow_op_call): + (JSC::JIT::emitSlow_op_call_eval): + (JSC::JIT::emitSlow_op_call_varargs): + (JSC::JIT::emitSlow_op_construct): + (JSC::JIT::compileOpCall): Filled out these cases, with call_eval #if'd out. + + * jit/JITInlineMethods.h: + (JSC::JIT::emitPutJITStubArgFromVirtualRegister): + (JSC::JIT::emitLoad): Restored some legacy "*CTIArg*" functions, + since I wanted to avoid the complexity of revamping the API here while + trying to bring it up. Eventually, we should re-remove all of these functions. + + (JSC::JIT::recordJumpTarget): Removed unnecessary macro cruft. You will + not silence me, Sam Weinig! The world will know that you are a crufty, + crufty, crufty programmer!!! + + * jit/JITOpcodes.cpp: + * jit/JITStubs.cpp: + (JSC::): + * jit/JITStubs.h: Changed up some offsets in the JITStackFrame class, since + and off-by-one error was causing stack misalignment. + +2009-05-13 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement op_eq_null and op_neq_null. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::set8): + (JSC::MacroAssemblerX86Common::setTest8): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_stricteq): + (JSC::JIT::emitSlow_op_stricteq): + (JSC::JIT::emit_op_nstricteq): + (JSC::JIT::emitSlow_op_nstricteq): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jsc.cpp: + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement op_new_error. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_error): + * jit/JITStubCall.h: + (JSC::JITStubCall::addArgument): Add a version of addArgument + that takes a constant JSValue. + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Remove now unused emitGetVariableObjectRegister and emitPutVariableObjectRegister. + + * jit/JIT.cpp: + * jit/JIT.h: + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement op_to_primitive and op_next_pname. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_construct_verify): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emitSlow_op_to_primitive): + (JSC::JIT::emitSlow_op_loop_if_true): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emit_op_next_pname): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add op_get_global_var, op_put_global_var, emit_op_get_scoped_var, emit_op_put_scoped_var and + op_unexpected_load. + + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::tagFor): + (JSC::JIT::payloadFor): + (JSC::JIT::emitLoad): + (JSC::JIT::emitStore): + (JSC::JIT::emitLoadReturnValue): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_unexpected_load): + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added overflow handling to op_sub. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_sub): + (JSC::JIT::emitSlowSub32InPlaceLeft): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Remove a function call by folding op_get_by_id and op_put_by_id into + their respective compile functions. + + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_id): + (JSC::JIT::emitSlow_op_get_by_id): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::emitSlow_op_put_by_id): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Make JITStubCall work in 64bit by making the stack index + step dependent on the size of void*. + + * jit/JITStubCall.h: + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::addArgument): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement simple version of property access opcodes + which just call a stub functions. + + * jit/JITOpcodes.cpp: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_put_by_id): + (JSC::JIT::emitSlow_op_get_by_id): + (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): + (JSC::JIT::emit_op_put_by_index): + (JSC::JIT::emit_op_put_getter): + (JSC::JIT::emit_op_put_setter): + (JSC::JIT::emit_op_del_by_id): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compilePutByIdHotPath): + * jit/JITStubCall.h: + (JSC::JITStubCall::addArgument): + * jsc.cpp: + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added work-around for XCode debugging echo problem. + + * jsc.cpp: + (runInteractive): + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added overflow handling to op_add. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlowAdd32InPlace): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add slow cases for op_jnless or emit_op_jnlesseq. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emitSlow_op_jnlesseq): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add implementations for op_jnless, emit_op_jnlesseq, op_loop_if_less and op_loop_if_lesseq. + No slow cases for op_jnless or emit_op_jnlesseq yet. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + * jit/JITOpcodes.cpp: + (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): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Turn the RECORD_JUMP_TARGET macro into an inline function. + + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::recordJumpTarget): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_jsr): + (JSC::JIT::emit_op_jmp_scopes): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Add MacroAssemblerX86Common::set8 to fix the build. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::set8): + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added overflow recovery for pre_inc and pre_dec. + + Turned some short-circuit code into early returns, as is the WebKit style. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emitSlow_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emitSlow_op_post_dec): + (JSC::JIT::emitSlow_op_pre_inc): + (JSC::JIT::emitSlow_op_pre_dec): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement op_jmp, op_loop, op_eq and op_neq. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_loop): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emitSlow_op_neq): + (JSC::JIT::emit_op_enter): + (JSC::JIT::emit_op_enter_with_activation): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement the slow cases for arithmetic opcodes. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_lshift): + (JSC::JIT::emitSlow_op_rshift): + (JSC::JIT::emitSlow_op_bitand): + (JSC::JIT::emitSlow_op_bitor): + (JSC::JIT::emitSlow_op_bitxor): + (JSC::JIT::emitSlow_op_bitnot): + (JSC::JIT::emitSlow_op_sub): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emitSlow_op_mod): + (JSC::JIT::emit_op_mod): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Implement op_bitnot. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::not32): + * assembler/X86Assembler.h: + (JSC::X86Assembler::notl_m): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_bitnot): + +2009-05-12 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add arithmetic opcode implementations from the old nitro-extreme branch. + + * jit/JIT.h: + * 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::emit_op_lshift): + (JSC::JIT::emitSlow_op_lshift): + (JSC::JIT::emit_op_rshift): + (JSC::JIT::emitSlow_op_rshift): + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emitBitAnd32Constant): + (JSC::JIT::emitBitAnd32InPlace): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emitSlow_op_bitor): + (JSC::JIT::emitBitOr32Constant): + (JSC::JIT::emitBitOr32InPlace): + (JSC::JIT::emit_op_bitxor): + (JSC::JIT::emitSlow_op_bitxor): + (JSC::JIT::emitBitXor32Constant): + (JSC::JIT::emitBitXor32InPlace): + (JSC::JIT::emit_op_bitnot): + (JSC::JIT::emitSlow_op_bitnot): + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emitSlow_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emitSlow_op_post_dec): + (JSC::JIT::emit_op_pre_inc): + (JSC::JIT::emitSlow_op_pre_inc): + (JSC::JIT::emit_op_pre_dec): + (JSC::JIT::emitSlow_op_pre_dec): + (JSC::JIT::emit_op_add): + (JSC::JIT::emitAdd32Constant): + (JSC::JIT::emitAdd32InPlace): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSlow_op_sub): + (JSC::JIT::emitSub32ConstantLeft): + (JSC::JIT::emitSub32ConstantRight): + (JSC::JIT::emitSub32InPlaceLeft): + (JSC::JIT::emitSub32InPlaceRight): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emitMul32Constant): + (JSC::JIT::emitMul32InPlace): + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + * jit/JITOpcodes.cpp: + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Removed JIT_OPTIMIZE_ARITHMETIC setting, since it was all about 32bit + value representations. + + Added JSAPIValueWrapper to the repository. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + * runtime/JSAPIValueWrapper.cpp: Added. + (JSC::JSAPIValueWrapper::toPrimitive): + (JSC::JSAPIValueWrapper::getPrimitiveNumber): + (JSC::JSAPIValueWrapper::toBoolean): + (JSC::JSAPIValueWrapper::toNumber): + (JSC::JSAPIValueWrapper::toString): + (JSC::JSAPIValueWrapper::toObject): + * runtime/JSAPIValueWrapper.h: Added. + (JSC::JSAPIValueWrapper::value): + (JSC::JSAPIValueWrapper::isAPIValueWrapper): + (JSC::JSAPIValueWrapper::JSAPIValueWrapper): + (JSC::jsAPIValueWrapper): + * wtf/Platform.h: + +2009-05-12 Geoffrey Garen <ggaren@apple.com> + + Turned on the JIT and got it building and running the most trivial of + programs. + + All configurable optimizations are turned off, and a few opcodes are ad + hoc #if'd out. + + So far, I've only merged op_mov and op_end, but some stub-reliant + opcodes work as-is from TOT. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::~CodeBlock): + * bytecode/CodeBlock.h: + * jit/JIT.cpp: + (JSC::JIT::compileOpStrictEq): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_lshift): + (JSC::JIT::emitSlow_op_lshift): + (JSC::JIT::emit_op_rshift): + (JSC::JIT::emitSlow_op_rshift): + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + (JSC::JIT::emit_op_bitand): + (JSC::JIT::emitSlow_op_bitand): + (JSC::JIT::emit_op_post_inc): + (JSC::JIT::emitSlow_op_post_inc): + (JSC::JIT::emit_op_post_dec): + (JSC::JIT::emitSlow_op_post_dec): + (JSC::JIT::emit_op_pre_inc): + (JSC::JIT::emitSlow_op_pre_inc): + (JSC::JIT::emit_op_pre_dec): + (JSC::JIT::emitSlow_op_pre_dec): + (JSC::JIT::emit_op_mod): + (JSC::JIT::emitSlow_op_mod): + (JSC::JIT::emit_op_add): + (JSC::JIT::emit_op_mul): + (JSC::JIT::emit_op_sub): + (JSC::JIT::compileBinaryArithOpSlowCase): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlow_op_mul): + * jit/JITCall.cpp: + (JSC::JIT::compileOpCallInitializeCallFrame): + (JSC::JIT::compileOpConstructSetupArgs): + (JSC::JIT::compileOpCallVarargs): + (JSC::JIT::compileOpCall): + (JSC::JIT::compileOpCallSlowCase): + * jit/JITInlineMethods.h: + (JSC::JIT::getConstantOperandImmediateInt): + (JSC::JIT::isOperandConstantImmediateInt): + (JSC::JIT::emitInitRegister): + (JSC::JIT::addSlowCase): + (JSC::JIT::addJump): + (JSC::JIT::emitJumpSlowToHot): + (JSC::JIT::tagFor): + (JSC::JIT::payloadFor): + (JSC::JIT::emitLoad): + (JSC::JIT::emitLoadReturnValue): + (JSC::JIT::emitStore): + (JSC::JIT::emitStoreReturnValue): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_mov): + (JSC::JIT::emit_op_end): + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_loop): + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_tear_off_activation): + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_construct_verify): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emit_op_loop_if_true): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emit_op_not): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_unexpected_load): + (JSC::JIT::emit_op_eq): + (JSC::JIT::emit_op_bitnot): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emit_op_neq): + (JSC::JIT::emit_op_bitxor): + (JSC::JIT::emit_op_bitor): + (JSC::JIT::emit_op_throw): + (JSC::JIT::emit_op_next_pname): + (JSC::JIT::emit_op_push_scope): + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emit_op_push_new_scope): + (JSC::JIT::emit_op_catch): + (JSC::JIT::emit_op_switch_imm): + (JSC::JIT::emit_op_switch_char): + (JSC::JIT::emit_op_switch_string): + (JSC::JIT::emit_op_new_error): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + (JSC::JIT::emit_op_convert_this): + (JSC::JIT::emit_op_profile_will_call): + (JSC::JIT::emit_op_profile_did_call): + (JSC::JIT::emitSlow_op_construct_verify): + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emitSlow_op_loop_if_less): + (JSC::JIT::emitSlow_op_loop_if_lesseq): + (JSC::JIT::emitSlow_op_put_by_val): + (JSC::JIT::emitSlow_op_not): + (JSC::JIT::emitSlow_op_instanceof): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emit_op_put_by_index): + (JSC::JIT::emit_op_put_getter): + (JSC::JIT::emit_op_put_setter): + (JSC::JIT::emit_op_del_by_id): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compilePutByIdHotPath): + * jit/JITStubCall.h: + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::addArgument): + (JSC::JITStubCall::call): + (JSC::JITStubCall::): + (JSC::CallEvalJITStub::CallEvalJITStub): + * jit/JITStubs.cpp: + (JSC::): + (JSC::JITStubs::cti_op_add): + (JSC::JITStubs::cti_op_pre_inc): + (JSC::JITStubs::cti_op_mul): + (JSC::JITStubs::cti_op_get_by_val): + (JSC::JITStubs::cti_op_get_by_val_string): + (JSC::JITStubs::cti_op_get_by_val_byte_array): + (JSC::JITStubs::cti_op_sub): + (JSC::JITStubs::cti_op_put_by_val): + (JSC::JITStubs::cti_op_put_by_val_array): + (JSC::JITStubs::cti_op_put_by_val_byte_array): + (JSC::JITStubs::cti_op_negate): + (JSC::JITStubs::cti_op_div): + (JSC::JITStubs::cti_op_pre_dec): + (JSC::JITStubs::cti_op_post_inc): + (JSC::JITStubs::cti_op_eq): + (JSC::JITStubs::cti_op_lshift): + (JSC::JITStubs::cti_op_bitand): + (JSC::JITStubs::cti_op_rshift): + (JSC::JITStubs::cti_op_bitnot): + (JSC::JITStubs::cti_op_mod): + (JSC::JITStubs::cti_op_neq): + (JSC::JITStubs::cti_op_post_dec): + (JSC::JITStubs::cti_op_urshift): + (JSC::JITStubs::cti_op_bitxor): + (JSC::JITStubs::cti_op_bitor): + (JSC::JITStubs::cti_op_switch_imm): + * jit/JITStubs.h: + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + * runtime/JSFunction.cpp: + (JSC::JSFunction::~JSFunction): + * runtime/JSValue.h: + (JSC::JSValue::payload): + * wtf/Platform.h: + +2009-05-07 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen. + + Add some new MacroAssembler and assembler functions that will be needed shortly. + + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::add32): + (JSC::MacroAssemblerX86Common::and32): + (JSC::MacroAssemblerX86Common::mul32): + (JSC::MacroAssemblerX86Common::neg32): + (JSC::MacroAssemblerX86Common::or32): + (JSC::MacroAssemblerX86Common::sub32): + (JSC::MacroAssemblerX86Common::xor32): + (JSC::MacroAssemblerX86Common::branchAdd32): + (JSC::MacroAssemblerX86Common::branchMul32): + (JSC::MacroAssemblerX86Common::branchSub32): + * assembler/X86Assembler.h: + (JSC::X86Assembler::): + (JSC::X86Assembler::addl_rm): + (JSC::X86Assembler::andl_mr): + (JSC::X86Assembler::andl_rm): + (JSC::X86Assembler::andl_im): + (JSC::X86Assembler::negl_r): + (JSC::X86Assembler::notl_r): + (JSC::X86Assembler::orl_rm): + (JSC::X86Assembler::orl_im): + (JSC::X86Assembler::subl_rm): + (JSC::X86Assembler::xorl_mr): + (JSC::X86Assembler::xorl_rm): + (JSC::X86Assembler::xorl_im): + (JSC::X86Assembler::imull_mr): + +2009-05-11 Sam Weinig <sam@webkit.org> + + Reviewed by Cameron Zwarich. + + Remove the NumberHeap. + + * JavaScriptCore.exp: + * runtime/Collector.cpp: + (JSC::Heap::Heap): + (JSC::Heap::destroy): + (JSC::Heap::recordExtraCost): + (JSC::Heap::heapAllocate): + (JSC::Heap::markConservatively): + (JSC::Heap::sweep): + (JSC::Heap::collect): + (JSC::Heap::objectCount): + (JSC::Heap::statistics): + (JSC::typeName): + (JSC::Heap::isBusy): + * runtime/Collector.h: + (JSC::Heap::globalData): + * runtime/JSCell.h: + +2009-05-11 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Land initial commit of new number representation for 32 bit platforms, + with JIT disabled. + + * API/APICast.h: + (toJS): + (toRef): + * API/JSCallbackObjectFunctions.h: + (JSC::::hasInstance): + (JSC::::toNumber): + (JSC::::toString): + * API/tests/testapi.c: + (EvilExceptionObject_convertToType): + * AllInOneFile.cpp: + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::valueToSourceString): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::emitUnexpectedLoad): + (JSC::keyForImmediateSwitch): + * bytecompiler/BytecodeGenerator.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::dumpRegisters): + (JSC::Interpreter::privateExecute): + * parser/Nodes.cpp: + (JSC::ArrayNode::emitBytecode): + (JSC::processClauseList): + * runtime/ArgList.h: + * runtime/Collector.h: + (JSC::sizeof): + * runtime/DateMath.cpp: + * runtime/ExceptionHelpers.h: + * runtime/InitializeThreading.cpp: + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + * runtime/JSCell.cpp: + * runtime/JSCell.h: + (JSC::JSCell::isAPIValueWrapper): + (JSC::JSValue::isString): + (JSC::JSValue::isGetterSetter): + (JSC::JSValue::isObject): + (JSC::JSValue::getString): + (JSC::JSValue::getObject): + (JSC::JSValue::getCallData): + (JSC::JSValue::getConstructData): + (JSC::JSValue::getUInt32): + (JSC::JSValue::marked): + (JSC::JSValue::toPrimitive): + (JSC::JSValue::getPrimitiveNumber): + (JSC::JSValue::toBoolean): + (JSC::JSValue::toNumber): + (JSC::JSValue::toString): + (JSC::JSValue::needsThisConversion): + (JSC::JSValue::toThisString): + (JSC::JSValue::getJSNumber): + (JSC::JSValue::toObject): + (JSC::JSValue::toThisObject): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + * runtime/JSGlobalObject.h: + (JSC::Structure::prototypeForLookup): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncParseInt): + * runtime/JSImmediate.h: + * runtime/JSNumberCell.cpp: Removed. + * runtime/JSNumberCell.h: Removed. + * runtime/JSObject.h: + (JSC::JSValue::get): + (JSC::JSValue::put): + * runtime/JSString.h: + (JSC::JSValue::toThisJSString): + * runtime/JSValue.cpp: + (JSC::JSValue::toInteger): + (JSC::JSValue::toIntegerPreserveNaN): + (JSC::JSValue::toObjectSlowCase): + (JSC::JSValue::toThisObjectSlowCase): + (JSC::JSValue::synthesizeObject): + (JSC::JSValue::synthesizePrototype): + (JSC::JSValue::description): + (JSC::nonInlineNaN): + * runtime/JSValue.h: + (JSC::JSValue::): + (JSC::EncodedJSValueHashTraits::emptyValue): + (JSC::jsNaN): + (JSC::operator==): + (JSC::operator!=): + (JSC::toInt32): + (JSC::toUInt32): + (JSC::JSValue::encode): + (JSC::JSValue::decode): + (JSC::JSValue::JSValue): + (JSC::JSValue::operator bool): + (JSC::JSValue::operator==): + (JSC::JSValue::operator!=): + (JSC::JSValue::isUndefined): + (JSC::JSValue::isNull): + (JSC::JSValue::isUndefinedOrNull): + (JSC::JSValue::isCell): + (JSC::JSValue::isInt32): + (JSC::JSValue::isUInt32): + (JSC::JSValue::isDouble): + (JSC::JSValue::isTrue): + (JSC::JSValue::isFalse): + (JSC::JSValue::tag): + (JSC::JSValue::asInt32): + (JSC::JSValue::asUInt32): + (JSC::JSValue::asDouble): + (JSC::JSValue::asCell): + (JSC::JSValue::isNumber): + (JSC::JSValue::isBoolean): + (JSC::JSValue::getBoolean): + (JSC::JSValue::uncheckedGetNumber): + (JSC::JSValue::toJSNumber): + (JSC::JSValue::getNumber): + (JSC::JSValue::toInt32): + (JSC::JSValue::toUInt32): + * runtime/Operations.h: + (JSC::JSValue::equal): + (JSC::JSValue::equalSlowCaseInline): + (JSC::JSValue::strictEqual): + (JSC::JSValue::strictEqualSlowCaseInline): + (JSC::jsLess): + (JSC::jsLessEq): + (JSC::jsAdd): + * runtime/PropertySlot.h: + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncCharAt): + (JSC::stringProtoFuncCharCodeAt): + (JSC::stringProtoFuncIndexOf): + * wtf/Platform.h: + +=== Start merge of nitro-extreme branch 2009-07-30 === + +2009-07-29 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by George Staikos. + + Resolve class/struct mixup in forward declarations + https://bugs.webkit.org/show_bug.cgi?id=27708 + + * API/JSClassRef.h: + * bytecode/SamplingTool.h: + * interpreter/Interpreter.h: + * jit/JIT.h: + * profiler/ProfileGenerator.h: + * profiler/Profiler.h: + * runtime/ClassInfo.h: + * runtime/ExceptionHelpers.h: + * runtime/JSByteArray.h: + * runtime/JSCell.h: + * runtime/JSFunction.h: + * runtime/JSGlobalData.h: + * runtime/JSObject.h: + * runtime/JSString.h: + +2009-07-28 Ada Chan <adachan@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=27236 + - Implement TCMalloc_SystemRelease and TCMalloc_SystemCommit for Windows. + - Use a background thread to periodically scavenge memory to release back to the system. + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_PageHeap::init): + (WTF::TCMalloc_PageHeap::runScavengerThread): + (WTF::TCMalloc_PageHeap::scavenge): + (WTF::TCMalloc_PageHeap::shouldContinueScavenging): + (WTF::TCMalloc_PageHeap::New): + (WTF::TCMalloc_PageHeap::AllocLarge): + (WTF::TCMalloc_PageHeap::Delete): + (WTF::TCMalloc_PageHeap::GrowHeap): + (WTF::sleep): + (WTF::TCMalloc_PageHeap::scavengerThread): + * wtf/TCSystemAlloc.cpp: + (TCMalloc_SystemRelease): + (TCMalloc_SystemCommit): + * wtf/TCSystemAlloc.h: + 2009-07-28 Xan Lopez <xlopez@igalia.com> Add new files, fixes distcheck. @@ -429,8 +7690,6 @@ 2009-07-20 Oliver Hunt <oliver@apple.com> - Reviewed by NOBODY (Build fix). - Build fix attempt #2 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: @@ -438,8 +7697,6 @@ 2009-07-20 Oliver Hunt <oliver@apple.com> - Reviewed by NOBODY (Build fix). - Build fix attempt #1 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: @@ -1455,8 +8712,6 @@ 2009-07-09 Oliver Hunt <oliver@apple.com> - Reviewed by NOBODY (Build fix). - * interpreter/Interpreter.cpp: (JSC::Interpreter::privateExecute): @@ -2091,8 +9346,6 @@ 2009-06-21 Oliver Hunt <oliver@apple.com> - Reviewed by NOBODY (Build fix). - Remove dead code. * runtime/LiteralParser.cpp: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi index 5a75ab7..15a0c0f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi @@ -255,6 +255,7 @@ 'runtime/JSString.cpp', 'runtime/JSString.h', 'runtime/JSType.h', + 'runtime/JSTypeInfo.h', 'runtime/JSValue.cpp', 'runtime/JSValue.h', 'runtime/JSVariableObject.cpp', @@ -265,6 +266,9 @@ 'runtime/LiteralParser.h', 'runtime/Lookup.cpp', 'runtime/Lookup.h', + 'runtime/MarkStack.cpp', + 'runtime/MarkStack.h', + 'runtime/MarkStackWin.cpp', 'runtime/MathObject.cpp', 'runtime/MathObject.h', 'runtime/NativeErrorConstructor.cpp', @@ -284,6 +288,8 @@ 'runtime/ObjectPrototype.h', 'runtime/Operations.cpp', 'runtime/Operations.h', + 'runtime/PropertyDescriptor.cpp', + 'runtime/PropertyDescriptor.h', 'runtime/PropertyMapHashTable.h', 'runtime/PropertyNameArray.cpp', 'runtime/PropertyNameArray.h', @@ -323,7 +329,6 @@ 'runtime/TimeoutChecker.cpp', 'runtime/TimeoutChecker.h', 'runtime/Tracing.h', - 'runtime/JSTypeInfo.h', 'runtime/UString.cpp', 'runtime/UString.h', 'wrec/CharacterClass.cpp', diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri index 85645be..8483469 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri @@ -50,12 +50,7 @@ win32-* { } } -win32-msvc*: INCLUDEPATH += $$PWD/os-win32 -wince* { - INCLUDEPATH += $$PWD/os-wince - INCLUDEPATH += $$PWD/os-win32 - SOURCES += $$PWD/os-wince/ce_time.cpp -} +wince*: SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.cpp include(pcre/pcre.pri) @@ -105,11 +100,13 @@ SOURCES += \ runtime/JSNotAnObject.cpp \ runtime/JSONObject.cpp \ runtime/LiteralParser.cpp \ + runtime/MarkStack.cpp \ runtime/TimeoutChecker.cpp \ bytecode/CodeBlock.cpp \ bytecode/StructureStubInfo.cpp \ bytecode/JumpTable.cpp \ assembler/ARMAssembler.cpp \ + assembler/MacroAssemblerARM.cpp \ jit/JIT.cpp \ jit/JITCall.cpp \ jit/JITArithmetic.cpp \ @@ -128,8 +125,13 @@ SOURCES += \ yarr/RegexJIT.cpp \ interpreter/RegisterFile.cpp -win32-*|wince*: SOURCES += jit/ExecutableAllocatorWin.cpp -else: SOURCES += jit/ExecutableAllocatorPosix.cpp +win32-*|wince* { + SOURCES += jit/ExecutableAllocatorWin.cpp \ + runtime/MarkStackWin.cpp +} else { + SOURCES += jit/ExecutableAllocatorPosix.cpp \ + runtime/MarkStackPosix.cpp +} # AllInOneFile.cpp helps gcc analize and optimize code # Other compilers may be able to do this at link time @@ -159,6 +161,7 @@ SOURCES += \ runtime/ErrorInstance.cpp \ runtime/ErrorPrototype.cpp \ interpreter/CallFrame.cpp \ + runtime/Executable.cpp \ runtime/FunctionConstructor.cpp \ runtime/FunctionPrototype.cpp \ runtime/GetterSetter.cpp \ @@ -167,6 +170,7 @@ SOURCES += \ runtime/InternalFunction.cpp \ runtime/Completion.cpp \ runtime/JSArray.cpp \ + runtime/JSAPIValueWrapper.cpp \ runtime/JSByteArray.cpp \ runtime/JSCell.cpp \ runtime/JSFunction.cpp \ @@ -192,6 +196,7 @@ SOURCES += \ runtime/Operations.cpp \ parser/Parser.cpp \ parser/ParserArena.cpp \ + runtime/PropertyDescriptor.cpp \ runtime/PropertyNameArray.cpp \ runtime/PropertySlot.cpp \ runtime/PrototypeFunction.cpp \ @@ -216,8 +221,7 @@ SOURCES += \ wtf/DateMath.cpp \ wtf/FastMalloc.cpp \ wtf/Threading.cpp \ - wtf/qt/MainThreadQt.cpp \ - parser/SourcePoolQt.cpp + wtf/qt/MainThreadQt.cpp !contains(DEFINES, ENABLE_SINGLE_THREADED=1) { SOURCES += wtf/qt/ThreadingQt.cpp diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pro new file mode 100644 index 0000000..0cd2e1a --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pro @@ -0,0 +1,69 @@ +# JavaScriptCore - qmake build info +CONFIG += building-libs +include($$PWD/../WebKit.pri) + +TEMPLATE = lib +CONFIG += staticlib +TARGET = JavaScriptCore + +CONFIG += depend_includepath + +contains(QT_CONFIG, embedded):CONFIG += embedded + +CONFIG(QTDIR_build) { + GENERATED_SOURCES_DIR = $$PWD/generated + OLDDESTDIR = $$DESTDIR + include($$QT_SOURCE_TREE/src/qbase.pri) + INSTALLS = + DESTDIR = $$OLDDESTDIR + PRECOMPILED_HEADER = $$PWD/../WebKit/qt/WebKit_pch.h + DEFINES *= NDEBUG +} + +isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp +GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP} + +INCLUDEPATH += $$GENERATED_SOURCES_DIR + +!CONFIG(QTDIR_build) { + CONFIG(debug, debug|release) { + OBJECTS_DIR = obj/debug + } else { # Release + OBJECTS_DIR = obj/release + } +} + +CONFIG(release):!CONFIG(QTDIR_build) { + contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols + unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions +} + +linux-*: DEFINES += HAVE_STDINT_H +freebsd-*: DEFINES += HAVE_PTHREAD_NP_H + +DEFINES += BUILD_WEBKIT + +win32-*: DEFINES += _HAS_TR1=0 + +# Pick up 3rdparty libraries from INCLUDE/LIB just like with MSVC +win32-g++ { + TMPPATH = $$quote($$(INCLUDE)) + QMAKE_INCDIR_POST += $$split(TMPPATH,";") + TMPPATH = $$quote($$(LIB)) + QMAKE_LIBDIR_POST += $$split(TMPPATH,";") +} + +DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 + +DEFINES += WTF_CHANGES=1 + +include(JavaScriptCore.pri) + +QMAKE_EXTRA_TARGETS += generated_files + +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/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp index dafc482..1324586 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "ARMAssembler.h" @@ -49,11 +49,11 @@ ARMWord* ARMAssembler::getLdrImmAddress(ARMWord* insn, uint32_t* constPool) return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK)); } -void ARMAssembler::linkBranch(void* code, JmpSrc from, void* to) +void ARMAssembler::linkBranch(void* code, JmpSrc from, void* to, int useConstantPool) { ARMWord* insn = reinterpret_cast<ARMWord*>(code) + (from.m_offset / sizeof(ARMWord)); - if (!from.m_latePatch) { + if (!useConstantPool) { int diff = reinterpret_cast<ARMWord*>(to) - reinterpret_cast<ARMWord*>(insn + 2); if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) { @@ -291,10 +291,10 @@ void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID bas if (offset <= 0xfff) dtr_u(isLoad, srcDst, base, offset); else if (offset <= 0xfffff) { - add_r(ARM::S0, base, OP2_IMM | (offset >> 12) | (10 << 8)); - dtr_u(isLoad, srcDst, ARM::S0, offset & 0xfff); + add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8)); + dtr_u(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff); } else { - ARMWord reg = getImm(offset, ARM::S0); + ARMWord reg = getImm(offset, ARMRegisters::S0); dtr_ur(isLoad, srcDst, base, reg); } } else { @@ -302,10 +302,10 @@ void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID bas if (offset <= 0xfff) dtr_d(isLoad, srcDst, base, offset); else if (offset <= 0xfffff) { - sub_r(ARM::S0, base, OP2_IMM | (offset >> 12) | (10 << 8)); - dtr_d(isLoad, srcDst, ARM::S0, offset & 0xfff); + sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8)); + dtr_d(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff); } else { - ARMWord reg = getImm(offset, ARM::S0); + ARMWord reg = getImm(offset, ARMRegisters::S0); dtr_dr(isLoad, srcDst, base, reg); } } @@ -319,30 +319,70 @@ void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterI op2 = lsl(index, scale); if (offset >= 0 && offset <= 0xfff) { - add_r(ARM::S0, base, op2); - dtr_u(isLoad, srcDst, ARM::S0, offset); + add_r(ARMRegisters::S0, base, op2); + dtr_u(isLoad, srcDst, ARMRegisters::S0, offset); return; } if (offset <= 0 && offset >= -0xfff) { - add_r(ARM::S0, base, op2); - dtr_d(isLoad, srcDst, ARM::S0, -offset); + add_r(ARMRegisters::S0, base, op2); + dtr_d(isLoad, srcDst, ARMRegisters::S0, -offset); return; } - moveImm(offset, ARM::S0); - add_r(ARM::S0, ARM::S0, op2); - dtr_ur(isLoad, srcDst, base, ARM::S0); + ldr_un_imm(ARMRegisters::S0, offset); + add_r(ARMRegisters::S0, ARMRegisters::S0, op2); + dtr_ur(isLoad, srcDst, base, ARMRegisters::S0); +} + +void ARMAssembler::doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset) +{ + if (offset & 0x3) { + if (offset <= 0x3ff && offset >= 0) { + fdtr_u(isLoad, srcDst, base, offset >> 2); + return; + } + if (offset <= 0x3ffff && offset >= 0) { + add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8)); + fdtr_u(isLoad, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff); + return; + } + offset = -offset; + + if (offset <= 0x3ff && offset >= 0) { + fdtr_d(isLoad, srcDst, base, offset >> 2); + return; + } + if (offset <= 0x3ffff && offset >= 0) { + sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8)); + fdtr_d(isLoad, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff); + return; + } + offset = -offset; + } + + ldr_un_imm(ARMRegisters::S0, offset); + add_r(ARMRegisters::S0, ARMRegisters::S0, base); + fdtr_u(isLoad, srcDst, ARMRegisters::S0, 0); } void* ARMAssembler::executableCopy(ExecutablePool* allocator) { + // 64-bit alignment is required for next constant pool and JIT code as well + m_buffer.flushWithoutBarrier(true); + if (m_buffer.uncheckedSize() & 0x7) + bkpt(0); + char* data = reinterpret_cast<char*>(m_buffer.executableCopy(allocator)); for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) { - ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + *iter); - ARMWord* offset = getLdrImmAddress(ldrAddr); - if (*offset != 0xffffffff) - linkBranch(data, JmpSrc(*iter), data + *offset); + // The last bit is set if the constant must be placed on constant pool. + int pos = (*iter) & (~0x1); + ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos); + ARMWord offset = *getLdrImmAddress(ldrAddr); + if (offset != 0xffffffff) { + JmpSrc jmpSrc(pos); + linkBranch(data, jmpSrc, data + offset, ((*iter) & 1)); + } } return data; @@ -350,4 +390,4 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator) } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h index d6bb43e..9f9a450 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h @@ -29,50 +29,55 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "AssemblerBufferWithConstantPool.h" #include <wtf/Assertions.h> namespace JSC { -typedef uint32_t ARMWord; - -namespace ARM { - typedef enum { - r0 = 0, - r1, - r2, - r3, - S0 = r3, - r4, - r5, - r6, - r7, - r8, - S1 = r8, - r9, - r10, - r11, - r12, - r13, - sp = r13, - r14, - lr = r14, - r15, - pc = r15 - } RegisterID; - - typedef enum { - fp0 //FIXME - } FPRegisterID; -} // namespace ARM + typedef uint32_t ARMWord; + + namespace ARMRegisters { + typedef enum { + r0 = 0, + r1, + r2, + r3, + S0 = r3, + r4, + r5, + r6, + r7, + r8, + S1 = r8, + r9, + r10, + r11, + r12, + r13, + sp = r13, + r14, + lr = r14, + r15, + pc = r15 + } RegisterID; + + typedef enum { + d0, + d1, + d2, + d3, + SD0 = d3 + } FPRegisterID; + + } // namespace ARMRegisters class ARMAssembler { public: - typedef ARM::RegisterID RegisterID; - typedef ARM::FPRegisterID FPRegisterID; + typedef ARMRegisters::RegisterID RegisterID; + typedef ARMRegisters::FPRegisterID FPRegisterID; typedef AssemblerBufferWithConstantPool<2048, 4, 4, ARMAssembler> ARMBuffer; - typedef WTF::SegmentedVector<int, 64> Jumps; + typedef SegmentedVector<int, 64> Jumps; ARMAssembler() { } @@ -115,13 +120,21 @@ namespace ARM { MVN = (0xf << 21), MUL = 0x00000090, MULL = 0x00c00090, + FADDD = 0x0e300b00, + FSUBD = 0x0e300b40, + FMULD = 0x0e200b00, + FCMPD = 0x0eb40b40, DTR = 0x05000000, LDRH = 0x00100090, STRH = 0x00000090, STMDB = 0x09200000, LDMIA = 0x08b00000, + FDTR = 0x0d000b00, B = 0x0a000000, BL = 0x0b000000, + FMSR = 0x0e000a10, + FSITOD = 0x0eb80bc0, + FMSTAT = 0x0ef1fa10, #if ARM_ARCH_VERSION >= 5 CLZ = 0x016f0f10, BKPT = 0xe120070, @@ -167,20 +180,16 @@ namespace ARM { public: JmpSrc() : m_offset(-1) - , m_latePatch(false) { } - void enableLatePatch() { m_latePatch = true; } private: JmpSrc(int offset) : m_offset(offset) - , m_latePatch(false) { } - int m_offset : 31; - int m_latePatch : 1; + int m_offset; }; class JmpDst { @@ -321,12 +330,12 @@ namespace ARM { void mov_r(int rd, ARMWord op2, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARM::r0, op2); + emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARMRegisters::r0, op2); } void movs_r(int rd, ARMWord op2, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | MOV | SET_CC, rd, ARM::r0, op2); + emitInst(static_cast<ARMWord>(cc) | MOV | SET_CC, rd, ARMRegisters::r0, op2); } void bic_r(int rd, int rn, ARMWord op2, Condition cc = AL) @@ -341,12 +350,12 @@ namespace ARM { void mvn_r(int rd, ARMWord op2, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | MVN, rd, ARM::r0, op2); + emitInst(static_cast<ARMWord>(cc) | MVN, rd, ARMRegisters::r0, op2); } void mvns_r(int rd, ARMWord op2, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | MVN | SET_CC, rd, ARM::r0, op2); + emitInst(static_cast<ARMWord>(cc) | MVN | SET_CC, rd, ARMRegisters::r0, op2); } void mul_r(int rd, int rn, int rm, Condition cc = AL) @@ -364,14 +373,34 @@ namespace ARM { m_buffer.putInt(static_cast<ARMWord>(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm)); } + void faddd_r(int dd, int dn, int dm, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FADDD, dd, dn, dm); + } + + void fsubd_r(int dd, int dn, int dm, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FSUBD, dd, dn, dm); + } + + void fmuld_r(int dd, int dn, int dm, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FMULD, dd, dn, dm); + } + + void fcmpd_r(int dd, int dm, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FCMPD, dd, 0, dm); + } + void ldr_imm(int rd, ARMWord imm, Condition cc = AL) { - m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARM::pc) | RD(rd), imm, true); + m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm, true); } void ldr_un_imm(int rd, ARMWord imm, Condition cc = AL) { - m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARM::pc) | RD(rd), imm); + m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm); } void dtr_u(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL) @@ -414,26 +443,53 @@ namespace ARM { emitInst(static_cast<ARMWord>(cc) | STRH | HDT_UH | DT_UP | DT_PRE, rd, rn, rm); } + void fdtr_u(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL) + { + ASSERT(op2 <= 0xff); + emitInst(static_cast<ARMWord>(cc) | FDTR | DT_UP | (isLoad ? DT_LOAD : 0), rd, rb, op2); + } + + void fdtr_d(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL) + { + ASSERT(op2 <= 0xff); + emitInst(static_cast<ARMWord>(cc) | FDTR | (isLoad ? DT_LOAD : 0), rd, rb, op2); + } + void push_r(int reg, Condition cc = AL) { ASSERT(ARMWord(reg) <= 0xf); - m_buffer.putInt(cc | DTR | DT_WB | RN(ARM::sp) | RD(reg) | 0x4); + m_buffer.putInt(cc | DTR | DT_WB | RN(ARMRegisters::sp) | RD(reg) | 0x4); } void pop_r(int reg, Condition cc = AL) { ASSERT(ARMWord(reg) <= 0xf); - m_buffer.putInt(cc | (DTR ^ DT_PRE) | DT_LOAD | DT_UP | RN(ARM::sp) | RD(reg) | 0x4); + m_buffer.putInt(cc | (DTR ^ DT_PRE) | DT_LOAD | DT_UP | RN(ARMRegisters::sp) | RD(reg) | 0x4); } inline void poke_r(int reg, Condition cc = AL) { - dtr_d(false, ARM::sp, 0, reg, cc); + dtr_d(false, ARMRegisters::sp, 0, reg, cc); } inline void peek_r(int reg, Condition cc = AL) { - dtr_u(true, reg, ARM::sp, 0, cc); + dtr_u(true, reg, ARMRegisters::sp, 0, cc); + } + + void fmsr_r(int dd, int rn, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FMSR, rn, dd, 0); + } + + void fsitod_r(int dd, int dm, Condition cc = AL) + { + emitInst(static_cast<ARMWord>(cc) | FSITOD, dd, 0, dm); + } + + void fmstat(Condition cc = AL) + { + m_buffer.putInt(static_cast<ARMWord>(cc) | FMSTAT); } #if ARM_ARCH_VERSION >= 5 @@ -449,49 +505,49 @@ namespace ARM { m_buffer.putInt(BKPT | ((value & 0xff0) << 4) | (value & 0xf)); #else // Cannot access to Zero memory address - dtr_dr(true, ARM::S0, ARM::S0, ARM::S0); + dtr_dr(true, ARMRegisters::S0, ARMRegisters::S0, ARMRegisters::S0); #endif } static ARMWord lsl(int reg, ARMWord value) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); ASSERT(value <= 0x1f); return reg | (value << 7) | 0x00; } static ARMWord lsr(int reg, ARMWord value) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); ASSERT(value <= 0x1f); return reg | (value << 7) | 0x20; } static ARMWord asr(int reg, ARMWord value) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); ASSERT(value <= 0x1f); return reg | (value << 7) | 0x40; } static ARMWord lsl_r(int reg, int shiftReg) { - ASSERT(reg <= ARM::pc); - ASSERT(shiftReg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); + ASSERT(shiftReg <= ARMRegisters::pc); return reg | (shiftReg << 8) | 0x10; } static ARMWord lsr_r(int reg, int shiftReg) { - ASSERT(reg <= ARM::pc); - ASSERT(shiftReg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); + ASSERT(shiftReg <= ARMRegisters::pc); return reg | (shiftReg << 8) | 0x30; } static ARMWord asr_r(int reg, int shiftReg) { - ASSERT(reg <= ARM::pc); - ASSERT(shiftReg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); + ASSERT(shiftReg <= ARMRegisters::pc); return reg | (shiftReg << 8) | 0x50; } @@ -507,6 +563,11 @@ namespace ARM { m_buffer.ensureSpace(insnSpace, constSpace); } + int sizeOfConstantPool() + { + return m_buffer.sizeOfConstantPool(); + } + JmpDst label() { return JmpDst(m_buffer.size()); @@ -515,16 +576,17 @@ namespace ARM { JmpDst align(int alignment) { while (!m_buffer.isAligned(alignment)) - mov_r(ARM::r0, ARM::r0); + mov_r(ARMRegisters::r0, ARMRegisters::r0); return label(); } - JmpSrc jmp(Condition cc = AL) + JmpSrc jmp(Condition cc = AL, int useConstantPool = 0) { - int s = size(); - ldr_un_imm(ARM::pc, 0xffffffff, cc); - m_jumps.append(s); + ensureSpace(sizeof(ARMWord), sizeof(ARMWord)); + int s = m_buffer.uncheckedSize(); + ldr_un_imm(ARMRegisters::pc, 0xffffffff, cc); + m_jumps.append(s | (useConstantPool & 0x1)); return JmpSrc(s); } @@ -533,7 +595,7 @@ namespace ARM { // Patching helpers static ARMWord* getLdrImmAddress(ARMWord* insn, uint32_t* constPool = 0); - static void linkBranch(void* code, JmpSrc from, void* to); + static void linkBranch(void* code, JmpSrc from, void* to, int useConstantPool = 0); static void patchPointerInternal(intptr_t from, void* to) { @@ -600,7 +662,7 @@ namespace ARM { static void linkCall(void* code, JmpSrc from, void* to) { - linkBranch(code, from, to); + linkBranch(code, from, to, true); } static void relinkCall(void* from, void* to) @@ -653,6 +715,7 @@ namespace ARM { void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset); void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset); + void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset); // Constant pool hnadlers @@ -666,25 +729,25 @@ namespace ARM { private: ARMWord RM(int reg) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); return reg; } ARMWord RS(int reg) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); return reg << 8; } ARMWord RD(int reg) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); return reg << 12; } ARMWord RN(int reg) { - ASSERT(reg <= ARM::pc); + ASSERT(reg <= ARMRegisters::pc); return reg << 16; } @@ -701,6 +764,6 @@ namespace ARM { } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #endif // ARMAssembler_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h index f7e2fb4..078de44 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) #include "AssemblerBuffer.h" #include <wtf/Assertions.h> @@ -37,7 +37,7 @@ namespace JSC { -namespace ARM { +namespace ARMRegisters { typedef enum { r0, r1, @@ -199,7 +199,7 @@ class ARMThumbImmediate { }; } PatternBytes; - ALWAYS_INLINE static int32_t countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N) + ALWAYS_INLINE static void countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N) { if (value & ~((1<<N)-1)) /* check for any of the top N bits (of 2N bits) are set */ \ value >>= N; /* if any were set, lose the bottom N */ \ @@ -407,8 +407,8 @@ register writeback class ARMv7Assembler { public: - typedef ARM::RegisterID RegisterID; - typedef ARM::FPRegisterID FPRegisterID; + typedef ARMRegisters::RegisterID RegisterID; + typedef ARMRegisters::FPRegisterID FPRegisterID; // (HS, LO, HI, LS) -> (AE, B, A, BE) // (VS, VC) -> (O, NO) @@ -442,7 +442,6 @@ public: { } - void enableLatePatch() { } private: JmpSrc(int offset) : m_offset(offset) @@ -481,7 +480,7 @@ private: // ARMv7, Appx-A.6.3 bool BadReg(RegisterID reg) { - return (reg == ARM::sp) || (reg == ARM::pc); + return (reg == ARMRegisters::sp) || (reg == ARMRegisters::pc); } bool isSingleRegister(FPRegisterID reg) @@ -693,16 +692,16 @@ public: void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isValid()); - if (rn == ARM::sp) { + if (rn == ARMRegisters::sp) { if (!(rd & 8) && imm.isUInt10()) { m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, imm.getUInt10() >> 2); return; - } else if ((rd == ARM::sp) && imm.isUInt9()) { + } else if ((rd == ARMRegisters::sp) && imm.isUInt9()) { m_formatter.oneWordOp9Imm7(OP_ADD_SP_imm_T2, imm.getUInt9() >> 2); return; } @@ -726,9 +725,9 @@ public: void add(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); m_formatter.twoWordOp12Reg4FourFours(OP_ADD_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); } @@ -750,9 +749,9 @@ public: void add_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isEncodedImm()); if (!((rd | rn) & 8)) { @@ -771,9 +770,9 @@ public: // Not allowed in an IT (if then) block? void add_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); m_formatter.twoWordOp12Reg4FourFours(OP_ADD_S_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); } @@ -839,7 +838,7 @@ public: // Only allowed in IT (if then) block if last instruction. JmpSrc blx(RegisterID rm) { - ASSERT(rm != ARM::pc); + ASSERT(rm != ARMRegisters::pc); m_formatter.oneWordOp8RegReg143(OP_BLX, rm, (RegisterID)8); return JmpSrc(m_formatter.size()); } @@ -858,7 +857,7 @@ public: void cmn(RegisterID rn, ARMThumbImmediate imm) { - ASSERT(rn != ARM::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isEncodedImm()); m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMN_imm, rn, (RegisterID)0xf, imm); @@ -866,7 +865,7 @@ public: void cmp(RegisterID rn, ARMThumbImmediate imm) { - ASSERT(rn != ARM::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isEncodedImm()); if (!(rn & 8) && imm.isUInt8()) @@ -877,7 +876,7 @@ public: void cmp(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { - ASSERT(rn != ARM::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); m_formatter.twoWordOp12Reg4FourFours(OP_CMP_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm)); } @@ -939,15 +938,15 @@ public: m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if, inst4if)); } - // rt == ARM::pc only allowed if last instruction in IT (if then) block. + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. void ldr(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) { - ASSERT(rn != ARM::pc); // LDR (literal) + ASSERT(rn != ARMRegisters::pc); // LDR (literal) ASSERT(imm.isUInt12()); if (!((rt | rn) & 8) && imm.isUInt7()) m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDR_imm_T1, imm.getUInt7() >> 2, rn, rt); - else if ((rn == ARM::sp) && !(rt & 8) && imm.isUInt10()) + else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10()) m_formatter.oneWordOp5Reg3Imm8(OP_LDR_imm_T2, rt, imm.getUInt10() >> 2); else m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, imm.getUInt12()); @@ -966,8 +965,8 @@ public: // if (wback) REG[rn] = _tmp void ldr(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) { - ASSERT(rt != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(index || wback); ASSERT(!wback | (rt != rn)); @@ -986,10 +985,10 @@ public: m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T4, rn, rt, offset); } - // rt == ARM::pc only allowed if last instruction in IT (if then) block. + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. void ldr(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) { - ASSERT(rn != ARM::pc); // LDR (literal) + ASSERT(rn != ARMRegisters::pc); // LDR (literal) ASSERT(!BadReg(rm)); ASSERT(shift <= 3); @@ -999,10 +998,10 @@ public: m_formatter.twoWordOp12Reg4FourFours(OP_LDR_reg_T2, rn, FourFours(rt, 0, shift, rm)); } - // rt == ARM::pc only allowed if last instruction in IT (if then) block. + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. void ldrh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) { - ASSERT(rn != ARM::pc); // LDR (literal) + ASSERT(rn != ARMRegisters::pc); // LDR (literal) ASSERT(imm.isUInt12()); if (!((rt | rn) & 8) && imm.isUInt6()) @@ -1024,8 +1023,8 @@ public: // if (wback) REG[rn] = _tmp void ldrh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) { - ASSERT(rt != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(index || wback); ASSERT(!wback | (rt != rn)); @@ -1047,7 +1046,7 @@ public: void ldrh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) { ASSERT(!BadReg(rt)); // Memory hint - ASSERT(rn != ARM::pc); // LDRH (literal) + ASSERT(rn != ARMRegisters::pc); // LDRH (literal) ASSERT(!BadReg(rm)); ASSERT(shift <= 3); @@ -1198,16 +1197,16 @@ public: m_formatter.twoWordOp12Reg4FourFours(OP_SMULL_T1, rn, FourFours(rdLo, rdHi, 0, rm)); } - // rt == ARM::pc only allowed if last instruction in IT (if then) block. + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. void str(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) { - ASSERT(rt != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isUInt12()); if (!((rt | rn) & 8) && imm.isUInt7()) m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STR_imm_T1, imm.getUInt7() >> 2, rn, rt); - else if ((rn == ARM::sp) && !(rt & 8) && imm.isUInt10()) + else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10()) m_formatter.oneWordOp5Reg3Imm8(OP_STR_imm_T2, rt, imm.getUInt10() >> 2); else m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T3, rn, rt, imm.getUInt12()); @@ -1226,8 +1225,8 @@ public: // if (wback) REG[rn] = _tmp void str(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) { - ASSERT(rt != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(index || wback); ASSERT(!wback | (rt != rn)); @@ -1246,10 +1245,10 @@ public: m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T4, rn, rt, offset); } - // rt == ARM::pc only allowed if last instruction in IT (if then) block. + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. void str(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) { - ASSERT(rn != ARM::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); ASSERT(shift <= 3); @@ -1262,12 +1261,12 @@ public: void sub(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isValid()); - if ((rn == ARM::sp) && (rd == ARM::sp) && imm.isUInt9()) { + if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2); return; } else if (!((rd | rn) & 8)) { @@ -1290,9 +1289,9 @@ public: void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); m_formatter.twoWordOp12Reg4FourFours(OP_SUB_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); } @@ -1310,12 +1309,12 @@ public: void sub_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(imm.isValid()); - if ((rn == ARM::sp) && (rd == ARM::sp) && imm.isUInt9()) { + if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2); return; } else if (!((rd | rn) & 8)) { @@ -1334,9 +1333,9 @@ public: // Not allowed in an IT (if then) block? void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { - ASSERT((rd != ARM::sp) || (rn == ARM::sp)); - ASSERT(rd != ARM::pc); - ASSERT(rn != ARM::pc); + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); ASSERT(!BadReg(rm)); m_formatter.twoWordOp12Reg4FourFours(OP_SUB_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); } @@ -1754,6 +1753,6 @@ private: } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) #endif // ARMAssembler_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h index 95b5afc..525fe98 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -173,7 +173,7 @@ public: struct Imm32 { explicit Imm32(int32_t value) : m_value(value) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM) , m_isPointer(false) #endif { @@ -182,7 +182,7 @@ public: #if !PLATFORM(X86_64) explicit Imm32(ImmPtr ptr) : m_value(ptr.asIntptr()) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM) , m_isPointer(true) #endif { @@ -190,7 +190,7 @@ public: #endif int32_t m_value; -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM) // We rely on being able to regenerate code to recover exception handling // information. Since ARMv7 supports 16-bit immediates there is a danger // that if pointer values change the layout of the generated code will change. @@ -320,11 +320,6 @@ public: return Call(jump.m_jmp, Linkable); } - void enableLatePatch() - { - m_jmp.enableLatePatch(); - } - JmpSrc m_jmp; private: Flags m_flags; @@ -361,11 +356,6 @@ public: masm->m_assembler.linkJump(m_jmp, label.m_label); } - void enableLatePatch() - { - m_jmp.enableLatePatch(); - } - private: JmpSrc m_jmp; }; @@ -378,6 +368,8 @@ public: friend class LinkBuffer; public: + typedef Vector<Jump, 16> JumpVector; + void link(AbstractMacroAssembler<AssemblerType>* masm) { size_t size = m_jumps.size(); @@ -408,9 +400,11 @@ public: { return !m_jumps.size(); } + + const JumpVector& jumps() { return m_jumps; } private: - Vector<Jump, 16> m_jumps; + JumpVector m_jumps; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h index f15b7f3..af3c3be 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h @@ -34,6 +34,8 @@ #include "AssemblerBuffer.h" #include <wtf/SegmentedVector.h> +#define ASSEMBLER_HAS_CONSTANT_POOL 1 + namespace JSC { /* @@ -84,7 +86,7 @@ namespace JSC { template <int maxPoolSize, int barrierSize, int maxInstructionSize, class AssemblerType> class AssemblerBufferWithConstantPool: public AssemblerBuffer { - typedef WTF::SegmentedVector<uint32_t, 512> LoadOffsets; + typedef SegmentedVector<uint32_t, 512> LoadOffsets; public: enum { UniqueConst, @@ -177,6 +179,11 @@ public: return AssemblerBuffer::size(); } + int uncheckedSize() + { + return AssemblerBuffer::size(); + } + void* executableCopy(ExecutablePool* allocator) { flushConstantPool(false); @@ -207,10 +214,10 @@ public: } // This flushing mechanism can be called after any unconditional jumps. - void flushWithoutBarrier() + void flushWithoutBarrier(bool isForced = false) { // Flush if constant pool is more than 60% full to avoid overuse of this function. - if (5 * m_numConsts > 3 * maxPoolSize / sizeof(uint32_t)) + if (isForced || 5 * m_numConsts > 3 * maxPoolSize / sizeof(uint32_t)) flushConstantPool(false); } @@ -219,6 +226,11 @@ public: return m_pool; } + int sizeOfConstantPool() + { + return m_numConsts; + } + private: void correctDeltas(int insnSize) { @@ -276,7 +288,8 @@ private: { if (m_numConsts == 0) return; - if ((m_maxDistance < nextInsnSize + m_lastConstDelta + barrierSize + (int)sizeof(uint32_t))) + int lastConstDelta = m_lastConstDelta > nextInsnSize ? m_lastConstDelta - nextInsnSize : 0; + if ((m_maxDistance < nextInsnSize + lastConstDelta + barrierSize + (int)sizeof(uint32_t))) flushConstantPool(); } @@ -284,8 +297,8 @@ private: { if (m_numConsts == 0) return; - if ((m_maxDistance < nextInsnSize + m_lastConstDelta + barrierSize + (int)sizeof(uint32_t)) || - (m_numConsts + nextConstSize / sizeof(uint32_t) >= maxPoolSize)) + if ((m_maxDistance < nextInsnSize + m_lastConstDelta + nextConstSize + barrierSize + (int)sizeof(uint32_t)) || + (m_numConsts * sizeof(uint32_t) + nextConstSize >= maxPoolSize)) flushConstantPool(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h index 9e1c5d3..2743ab4 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h @@ -30,11 +30,11 @@ #if ENABLE(ASSEMBLER) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) #include "MacroAssemblerARMv7.h" namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }; -#elif PLATFORM(ARM) +#elif PLATFORM(ARM_TRADITIONAL) #include "MacroAssemblerARM.h" namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp new file mode 100644 index 0000000..43648c4 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 University of Szeged + * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) + +#include "MacroAssemblerARM.h" + +#if PLATFORM(LINUX) +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <elf.h> +#include <asm/hwcap.h> +#endif + +namespace JSC { + +static bool isVFPPresent() +{ +#if PLATFORM(LINUX) + int fd = open("/proc/self/auxv", O_RDONLY); + if (fd > 0) { + Elf32_auxv_t aux; + while (read(fd, &aux, sizeof(Elf32_auxv_t))) { + if (aux.a_type == AT_HWCAP) { + close(fd); + return aux.a_un.a_val & HWCAP_VFP; + } + } + close(fd); + } +#endif + + return false; +} + +const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent(); + +} + +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h index 27879a9..0c696c9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -30,7 +30,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "ARMAssembler.h" #include "AbstractMacroAssembler.h" @@ -57,15 +57,14 @@ public: }; enum DoubleCondition { - DoubleEqual, //FIXME - DoubleNotEqual, //FIXME - DoubleGreaterThan, //FIXME - DoubleGreaterThanOrEqual, //FIXME - DoubleLessThan, //FIXME - DoubleLessThanOrEqual, //FIXME + DoubleEqual = ARMAssembler::EQ, + DoubleGreaterThan = ARMAssembler::GT, + DoubleGreaterThanOrEqual = ARMAssembler::GE, + DoubleLessThan = ARMAssembler::LT, + DoubleLessThanOrEqual = ARMAssembler::LE, }; - static const RegisterID stackPointerRegister = ARM::sp; + static const RegisterID stackPointerRegister = ARMRegisters::sp; static const Scale ScalePtr = TimesFour; @@ -76,20 +75,20 @@ public: void add32(Imm32 imm, Address address) { - load32(address, ARM::S1); - add32(imm, ARM::S1); - store32(ARM::S1, address); + load32(address, ARMRegisters::S1); + add32(imm, ARMRegisters::S1); + store32(ARMRegisters::S1, address); } void add32(Imm32 imm, RegisterID dest) { - m_assembler.adds_r(dest, dest, m_assembler.getImm(imm.m_value, ARM::S0)); + m_assembler.adds_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void add32(Address src, RegisterID dest) { - load32(src, ARM::S1); - add32(ARM::S1, dest); + load32(src, ARMRegisters::S1); + add32(ARMRegisters::S1, dest); } void and32(RegisterID src, RegisterID dest) @@ -99,7 +98,7 @@ public: void and32(Imm32 imm, RegisterID dest) { - ARMWord w = m_assembler.getImm(imm.m_value, ARM::S0, true); + ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true); if (w & ARMAssembler::OP2_INV_IMM) m_assembler.bics_r(dest, dest, w & ~ARMAssembler::OP2_INV_IMM); else @@ -119,16 +118,16 @@ public: void mul32(RegisterID src, RegisterID dest) { if (src == dest) { - move(src, ARM::S0); - src = ARM::S0; + move(src, ARMRegisters::S0); + src = ARMRegisters::S0; } m_assembler.muls_r(dest, dest, src); } void mul32(Imm32 imm, RegisterID src, RegisterID dest) { - move(imm, ARM::S0); - m_assembler.muls_r(dest, src, ARM::S0); + move(imm, ARMRegisters::S0); + m_assembler.muls_r(dest, src, ARMRegisters::S0); } void not32(RegisterID dest) @@ -143,7 +142,7 @@ public: void or32(Imm32 imm, RegisterID dest) { - m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARM::S0)); + m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void rshift32(RegisterID shift_amount, RegisterID dest) @@ -163,20 +162,20 @@ public: void sub32(Imm32 imm, RegisterID dest) { - m_assembler.subs_r(dest, dest, m_assembler.getImm(imm.m_value, ARM::S0)); + m_assembler.subs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void sub32(Imm32 imm, Address address) { - load32(address, ARM::S1); - sub32(imm, ARM::S1); - store32(ARM::S1, address); + load32(address, ARMRegisters::S1); + sub32(imm, ARMRegisters::S1); + store32(ARMRegisters::S1, address); } void sub32(Address src, RegisterID dest) { - load32(src, ARM::S1); - sub32(ARM::S1, dest); + load32(src, ARMRegisters::S1); + sub32(ARMRegisters::S1, dest); } void xor32(RegisterID src, RegisterID dest) @@ -186,7 +185,7 @@ public: void xor32(Imm32 imm, RegisterID dest) { - m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARM::S0)); + m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void load32(ImplicitAddress address, RegisterID dest) @@ -202,8 +201,8 @@ public: DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { DataLabel32 dataLabel(this); - m_assembler.ldr_un_imm(ARM::S0, 0); - m_assembler.dtr_ur(true, dest, address.base, ARM::S0); + m_assembler.ldr_un_imm(ARMRegisters::S0, 0); + m_assembler.dtr_ur(true, dest, address.base, ARMRegisters::S0); return dataLabel; } @@ -216,18 +215,18 @@ public: void load16(BaseIndex address, RegisterID dest) { - m_assembler.add_r(ARM::S0, address.base, m_assembler.lsl(address.index, address.scale)); + m_assembler.add_r(ARMRegisters::S0, address.base, m_assembler.lsl(address.index, address.scale)); if (address.offset>=0) - m_assembler.ldrh_u(dest, ARM::S0, ARMAssembler::getOp2Byte(address.offset)); + m_assembler.ldrh_u(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(address.offset)); else - m_assembler.ldrh_d(dest, ARM::S0, ARMAssembler::getOp2Byte(-address.offset)); + m_assembler.ldrh_d(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(-address.offset)); } DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) { DataLabel32 dataLabel(this); - m_assembler.ldr_un_imm(ARM::S0, 0); - m_assembler.dtr_ur(false, src, address.base, ARM::S0); + m_assembler.ldr_un_imm(ARMRegisters::S0, 0); + m_assembler.dtr_ur(false, src, address.base, ARMRegisters::S0); return dataLabel; } @@ -243,21 +242,27 @@ public: void store32(Imm32 imm, ImplicitAddress address) { - move(imm, ARM::S1); - store32(ARM::S1, address); + if (imm.m_isPointer) + m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value); + else + move(imm, ARMRegisters::S1); + store32(ARMRegisters::S1, address); } void store32(RegisterID src, void* address) { - m_assembler.moveImm(reinterpret_cast<ARMWord>(address), ARM::S0); - m_assembler.dtr_u(false, src, ARM::S0, 0); + m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address)); + m_assembler.dtr_u(false, src, ARMRegisters::S0, 0); } void store32(Imm32 imm, void* address) { - m_assembler.moveImm(reinterpret_cast<ARMWord>(address), ARM::S0); - m_assembler.moveImm(imm.m_value, ARM::S1); - m_assembler.dtr_u(false, ARM::S1, ARM::S0, 0); + m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address)); + if (imm.m_isPointer) + m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value); + else + m_assembler.moveImm(imm.m_value, ARMRegisters::S1); + m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0); } void pop(RegisterID dest) @@ -272,19 +277,22 @@ public: void push(Address address) { - load32(address, ARM::S1); - push(ARM::S1); + load32(address, ARMRegisters::S1); + push(ARMRegisters::S1); } void push(Imm32 imm) { - move(imm, ARM::S0); - push(ARM::S0); + move(imm, ARMRegisters::S0); + push(ARMRegisters::S0); } void move(Imm32 imm, RegisterID dest) { - m_assembler.moveImm(imm.m_value, dest); + if (imm.m_isPointer) + m_assembler.ldr_un_imm(dest, imm.m_value); + else + m_assembler.moveImm(imm.m_value, dest); } void move(RegisterID src, RegisterID dest) @@ -294,14 +302,14 @@ public: void move(ImmPtr imm, RegisterID dest) { - m_assembler.mov_r(dest, m_assembler.getImm(reinterpret_cast<ARMWord>(imm.m_value), ARM::S0)); + move(Imm32(imm), dest); } void swap(RegisterID reg1, RegisterID reg2) { - m_assembler.mov_r(ARM::S0, reg1); + m_assembler.mov_r(ARMRegisters::S0, reg1); m_assembler.mov_r(reg1, reg2); - m_assembler.mov_r(reg2, ARM::S0); + m_assembler.mov_r(reg2, ARMRegisters::S0); } void signExtend32ToPtr(RegisterID src, RegisterID dest) @@ -316,40 +324,44 @@ public: move(src, dest); } - Jump branch32(Condition cond, RegisterID left, RegisterID right) + Jump branch32(Condition cond, RegisterID left, RegisterID right, int useConstantPool = 0) { m_assembler.cmp_r(left, right); - return Jump(m_assembler.jmp(ARMCondition(cond))); + return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool)); } - Jump branch32(Condition cond, RegisterID left, Imm32 right) + Jump branch32(Condition cond, RegisterID left, Imm32 right, int useConstantPool = 0) { - m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARM::S0)); - return Jump(m_assembler.jmp(ARMCondition(cond))); + if (right.m_isPointer) { + m_assembler.ldr_un_imm(ARMRegisters::S0, right.m_value); + m_assembler.cmp_r(left, ARMRegisters::S0); + } else + m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0)); + return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool)); } Jump branch32(Condition cond, RegisterID left, Address right) { - load32(right, ARM::S1); - return branch32(cond, left, ARM::S1); + load32(right, ARMRegisters::S1); + return branch32(cond, left, ARMRegisters::S1); } Jump branch32(Condition cond, Address left, RegisterID right) { - load32(left, ARM::S1); - return branch32(cond, ARM::S1, right); + load32(left, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); } Jump branch32(Condition cond, Address left, Imm32 right) { - load32(left, ARM::S1); - return branch32(cond, ARM::S1, right); + load32(left, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); } Jump branch32(Condition cond, BaseIndex left, Imm32 right) { - load32(left, ARM::S1); - return branch32(cond, ARM::S1, right); + load32(left, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); } Jump branch16(Condition cond, BaseIndex left, RegisterID right) @@ -363,9 +375,9 @@ public: Jump branch16(Condition cond, BaseIndex left, Imm32 right) { - load16(left, ARM::S0); - move(right, ARM::S1); - m_assembler.cmp_r(ARM::S0, ARM::S1); + load16(left, ARMRegisters::S0); + move(right, ARMRegisters::S1); + m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S1); return m_assembler.jmp(ARMCondition(cond)); } @@ -379,9 +391,9 @@ public: Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1)) { ASSERT((cond == Zero) || (cond == NonZero)); - ARMWord w = m_assembler.getImm(mask.m_value, ARM::S0, true); + ARMWord w = m_assembler.getImm(mask.m_value, ARMRegisters::S0, true); if (w & ARMAssembler::OP2_INV_IMM) - m_assembler.bics_r(ARM::S0, reg, w & ~ARMAssembler::OP2_INV_IMM); + m_assembler.bics_r(ARMRegisters::S0, reg, w & ~ARMAssembler::OP2_INV_IMM); else m_assembler.tst_r(reg, w); return Jump(m_assembler.jmp(ARMCondition(cond))); @@ -389,14 +401,14 @@ public: Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1)) { - load32(address, ARM::S1); - return branchTest32(cond, ARM::S1, mask); + load32(address, ARMRegisters::S1); + return branchTest32(cond, ARMRegisters::S1, mask); } Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1)) { - load32(address, ARM::S1); - return branchTest32(cond, ARM::S1, mask); + load32(address, ARMRegisters::S1); + return branchTest32(cond, ARMRegisters::S1, mask); } Jump jump() @@ -406,12 +418,12 @@ public: void jump(RegisterID target) { - move(target, ARM::pc); + move(target, ARMRegisters::pc); } void jump(Address address) { - load32(address, ARM::pc); + load32(address, ARMRegisters::pc); } Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest) @@ -431,11 +443,11 @@ public: void mull32(RegisterID src1, RegisterID src2, RegisterID dest) { if (src1 == dest) { - move(src1, ARM::S0); - src1 = ARM::S0; + move(src1, ARMRegisters::S0); + src1 = ARMRegisters::S0; } - m_assembler.mull_r(ARM::S1, dest, src2, src1); - m_assembler.cmp_r(ARM::S1, m_assembler.asr(dest, 31)); + m_assembler.mull_r(ARMRegisters::S1, dest, src2, src1); + m_assembler.cmp_r(ARMRegisters::S1, m_assembler.asr(dest, 31)); } Jump branchMul32(Condition cond, RegisterID src, RegisterID dest) @@ -454,8 +466,8 @@ public: { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); if (cond == Overflow) { - move(imm, ARM::S0); - mull32(ARM::S0, src, dest); + move(imm, ARMRegisters::S0); + mull32(ARMRegisters::S0, src, dest); cond = NonZero; } else @@ -485,13 +497,13 @@ public: Call nearCall() { prepareCall(); - return Call(m_assembler.jmp(), Call::LinkableNear); + return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::LinkableNear); } Call call(RegisterID target) { prepareCall(); - move(ARM::pc, target); + move(ARMRegisters::pc, target); JmpSrc jmpSrc; return Call(jmpSrc, Call::None); } @@ -503,7 +515,7 @@ public: void ret() { - pop(ARM::pc); + pop(ARMRegisters::pc); } void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) @@ -515,67 +527,67 @@ public: void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest) { - m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARM::S0)); + m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0)); m_assembler.mov_r(dest, ARMAssembler::getOp2(0)); m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond)); } void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest) { - load32(address, ARM::S1); + load32(address, ARMRegisters::S1); if (mask.m_value == -1) - m_assembler.cmp_r(0, ARM::S1); + m_assembler.cmp_r(0, ARMRegisters::S1); else - m_assembler.tst_r(ARM::S1, m_assembler.getImm(mask.m_value, ARM::S0)); + m_assembler.tst_r(ARMRegisters::S1, m_assembler.getImm(mask.m_value, ARMRegisters::S0)); m_assembler.mov_r(dest, ARMAssembler::getOp2(0)); m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond)); } void add32(Imm32 imm, RegisterID src, RegisterID dest) { - m_assembler.add_r(dest, src, m_assembler.getImm(imm.m_value, ARM::S0)); + m_assembler.add_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void add32(Imm32 imm, AbsoluteAddress address) { - m_assembler.moveImm(reinterpret_cast<ARMWord>(address.m_ptr), ARM::S1); - m_assembler.dtr_u(true, ARM::S1, ARM::S1, 0); - add32(imm, ARM::S1); - m_assembler.moveImm(reinterpret_cast<ARMWord>(address.m_ptr), ARM::S0); - m_assembler.dtr_u(false, ARM::S1, ARM::S0, 0); + m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr)); + m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0); + add32(imm, ARMRegisters::S1); + m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr)); + m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0); } void sub32(Imm32 imm, AbsoluteAddress address) { - m_assembler.moveImm(reinterpret_cast<ARMWord>(address.m_ptr), ARM::S1); - m_assembler.dtr_u(true, ARM::S1, ARM::S1, 0); - sub32(imm, ARM::S1); - m_assembler.moveImm(reinterpret_cast<ARMWord>(address.m_ptr), ARM::S0); - m_assembler.dtr_u(false, ARM::S1, ARM::S0, 0); + m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr)); + m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0); + sub32(imm, ARMRegisters::S1); + m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr)); + m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0); } void load32(void* address, RegisterID dest) { - m_assembler.moveImm(reinterpret_cast<ARMWord>(address), ARM::S0); - m_assembler.dtr_u(true, dest, ARM::S0, 0); + m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address)); + m_assembler.dtr_u(true, dest, ARMRegisters::S0, 0); } Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right) { - load32(left.m_ptr, ARM::S1); - return branch32(cond, ARM::S1, right); + load32(left.m_ptr, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); } Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right) { - load32(left.m_ptr, ARM::S1); - return branch32(cond, ARM::S1, right); + load32(left.m_ptr, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); } Call call() { prepareCall(); - return Call(m_assembler.jmp(), Call::Linkable); + return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::Linkable); } Call tailRecursiveCall() @@ -597,25 +609,23 @@ public: Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) { - dataLabel = moveWithPatch(initialRightValue, ARM::S1); - Jump jump = branch32(cond, left, ARM::S1); - jump.enableLatePatch(); + dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S1); + Jump jump = branch32(cond, left, ARMRegisters::S1, true); return jump; } Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) { - load32(left, ARM::S1); - dataLabel = moveWithPatch(initialRightValue, ARM::S0); - Jump jump = branch32(cond, ARM::S0, ARM::S1); - jump.enableLatePatch(); + load32(left, ARMRegisters::S1); + dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0); + Jump jump = branch32(cond, ARMRegisters::S0, ARMRegisters::S1, true); return jump; } DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address) { - DataLabelPtr dataLabel = moveWithPatch(initialValue, ARM::S1); - store32(ARM::S1, address); + DataLabelPtr dataLabel = moveWithPatch(initialValue, ARMRegisters::S1); + store32(ARMRegisters::S1, address); return dataLabel; } @@ -627,7 +637,7 @@ public: // Floating point operators bool supportsFloatingPoint() const { - return false; + return s_isVFPPresent; } bool supportsFloatingPointTruncate() const @@ -637,74 +647,58 @@ public: void loadDouble(ImplicitAddress address, FPRegisterID dest) { - UNUSED_PARAM(address); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + m_assembler.doubleTransfer(true, dest, address.base, address.offset); } void storeDouble(FPRegisterID src, ImplicitAddress address) { - UNUSED_PARAM(src); - UNUSED_PARAM(address); - ASSERT_NOT_REACHED(); + m_assembler.doubleTransfer(false, src, address.base, address.offset); } void addDouble(FPRegisterID src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + m_assembler.faddd_r(dest, dest, src); } void addDouble(Address src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + loadDouble(src, ARMRegisters::SD0); + addDouble(ARMRegisters::SD0, dest); } void subDouble(FPRegisterID src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + m_assembler.fsubd_r(dest, dest, src); } void subDouble(Address src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + loadDouble(src, ARMRegisters::SD0); + subDouble(ARMRegisters::SD0, dest); } void mulDouble(FPRegisterID src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + m_assembler.fmuld_r(dest, dest, src); } void mulDouble(Address src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + loadDouble(src, ARMRegisters::SD0); + mulDouble(ARMRegisters::SD0, dest); } void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { - UNUSED_PARAM(src); - UNUSED_PARAM(dest); - ASSERT_NOT_REACHED(); + m_assembler.fmsr_r(dest, src); + m_assembler.fsitod_r(dest, dest); } Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) { - UNUSED_PARAM(cond); - UNUSED_PARAM(left); - UNUSED_PARAM(right); - ASSERT_NOT_REACHED(); - return jump(); + m_assembler.fcmpd_r(left, right); + m_assembler.fmstat(); + return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond))); } // Truncates 'src' to an integer, and places the resulting 'dest'. @@ -725,46 +719,56 @@ protected: return static_cast<ARMAssembler::Condition>(cond); } + void ensureSpace(int insnSpace, int constSpace) + { + m_assembler.ensureSpace(insnSpace, constSpace); + } + + int sizeOfConstantPool() + { + return m_assembler.sizeOfConstantPool(); + } + void prepareCall() { - m_assembler.ensureSpace(3 * sizeof(ARMWord), sizeof(ARMWord)); + ensureSpace(3 * sizeof(ARMWord), sizeof(ARMWord)); // S0 might be used for parameter passing - m_assembler.add_r(ARM::S1, ARM::pc, ARMAssembler::OP2_IMM | 0x4); - m_assembler.push_r(ARM::S1); + m_assembler.add_r(ARMRegisters::S1, ARMRegisters::pc, ARMAssembler::OP2_IMM | 0x4); + m_assembler.push_r(ARMRegisters::S1); } void call32(RegisterID base, int32_t offset) { - if (base == ARM::sp) + if (base == ARMRegisters::sp) offset += 4; if (offset >= 0) { if (offset <= 0xfff) { prepareCall(); - m_assembler.dtr_u(true, ARM::pc, base, offset); + m_assembler.dtr_u(true, ARMRegisters::pc, base, offset); } else if (offset <= 0xfffff) { - m_assembler.add_r(ARM::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8)); + m_assembler.add_r(ARMRegisters::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8)); prepareCall(); - m_assembler.dtr_u(true, ARM::pc, ARM::S0, offset & 0xfff); + m_assembler.dtr_u(true, ARMRegisters::pc, ARMRegisters::S0, offset & 0xfff); } else { - ARMWord reg = m_assembler.getImm(offset, ARM::S0); + ARMWord reg = m_assembler.getImm(offset, ARMRegisters::S0); prepareCall(); - m_assembler.dtr_ur(true, ARM::pc, base, reg); + m_assembler.dtr_ur(true, ARMRegisters::pc, base, reg); } } else { offset = -offset; if (offset <= 0xfff) { prepareCall(); - m_assembler.dtr_d(true, ARM::pc, base, offset); + m_assembler.dtr_d(true, ARMRegisters::pc, base, offset); } else if (offset <= 0xfffff) { - m_assembler.sub_r(ARM::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8)); + m_assembler.sub_r(ARMRegisters::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8)); prepareCall(); - m_assembler.dtr_d(true, ARM::pc, ARM::S0, offset & 0xfff); + m_assembler.dtr_d(true, ARMRegisters::pc, ARMRegisters::S0, offset & 0xfff); } else { - ARMWord reg = m_assembler.getImm(offset, ARM::S0); + ARMWord reg = m_assembler.getImm(offset, ARMRegisters::S0); prepareCall(); - m_assembler.dtr_dr(true, ARM::pc, base, reg); + m_assembler.dtr_dr(true, ARMRegisters::pc, base, reg); } } } @@ -788,10 +792,11 @@ private: ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress()); } + static const bool s_isVFPPresent; }; } -#endif +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #endif // MacroAssemblerARM_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h index f7a8402..999056b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -39,9 +39,9 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7? // - dTR is likely used more than aTR, and we'll get better instruction // encoding if it's in the low 8 registers. - static const ARM::RegisterID dataTempRegister = ARM::ip; - static const RegisterID addressTempRegister = ARM::r3; - static const FPRegisterID fpTempRegister = ARM::d7; + static const ARMRegisters::RegisterID dataTempRegister = ARMRegisters::ip; + static const RegisterID addressTempRegister = ARMRegisters::r3; + static const FPRegisterID fpTempRegister = ARMRegisters::d7; struct ArmAddress { enum AddressType { @@ -102,8 +102,8 @@ public: DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS, }; - static const RegisterID stackPointerRegister = ARM::sp; - static const RegisterID linkRegister = ARM::lr; + static const RegisterID stackPointerRegister = ARMRegisters::sp; + static const RegisterID linkRegister = ARMRegisters::lr; // Integer arithmetic operations: // @@ -532,6 +532,7 @@ public: Jump branchTruncateDoubleToInt32(FPRegisterID, RegisterID) { ASSERT_NOT_REACHED(); + return jump(); } @@ -546,13 +547,13 @@ public: void pop(RegisterID dest) { // store postindexed with writeback - m_assembler.ldr(dest, ARM::sp, sizeof(void*), false, true); + m_assembler.ldr(dest, ARMRegisters::sp, sizeof(void*), false, true); } void push(RegisterID src) { // store preindexed with writeback - m_assembler.str(src, ARM::sp, -sizeof(void*), true, true); + m_assembler.str(src, ARMRegisters::sp, -sizeof(void*), true, true); } void push(Address address) @@ -1038,7 +1039,7 @@ protected: return addressTempRegister; } - DataLabel32 moveFixedWidthEncoding(Imm32 imm, RegisterID dst) + void moveFixedWidthEncoding(Imm32 imm, RegisterID dst) { uint32_t value = imm.m_value; m_assembler.movT3(dst, ARMThumbImmediate::makeUInt16(value & 0xffff)); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 341a7ff..568260a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -37,7 +37,7 @@ // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid // instruction address on the platform (for example, check any alignment requirements). -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded // into the processor are decorated with the bottom bit set, indicating that this is // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both @@ -124,7 +124,7 @@ public: } explicit MacroAssemblerCodePtr(void* value) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // Decorate the pointer as a thumb code pointer. : m_value(reinterpret_cast<char*>(value) + 1) #else @@ -141,7 +141,7 @@ public: } void* executableAddress() const { return m_value; } -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // To use this pointer as a data address remove the decoration. void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; } #else diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h index 0b9ff35..6e96240 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h @@ -51,6 +51,8 @@ public: using MacroAssemblerX86Common::store32; using MacroAssemblerX86Common::branch32; using MacroAssemblerX86Common::call; + using MacroAssemblerX86Common::loadDouble; + using MacroAssemblerX86Common::convertInt32ToDouble; void add32(Imm32 imm, RegisterID src, RegisterID dest) { @@ -87,6 +89,17 @@ public: m_assembler.movl_mr(address, dest); } + void loadDouble(void* address, FPRegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.movsd_mr(address, dest); + } + + void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) + { + m_assembler.cvtsi2sd_mr(src.m_ptr, dest); + } + void store32(Imm32 imm, void* address) { m_assembler.movl_i32m(imm.m_value, address); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h index cea691e..61e0e17 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -57,13 +57,14 @@ public: enum DoubleCondition { DoubleEqual = X86Assembler::ConditionE, + DoubleNotEqual = X86Assembler::ConditionNE, DoubleGreaterThan = X86Assembler::ConditionA, DoubleGreaterThanOrEqual = X86Assembler::ConditionAE, DoubleLessThan = X86Assembler::ConditionB, DoubleLessThanOrEqual = X86Assembler::ConditionBE, }; - static const RegisterID stackPointerRegister = X86::esp; + static const RegisterID stackPointerRegister = X86Registers::esp; // Integer arithmetic operations: // @@ -91,6 +92,11 @@ public: { m_assembler.addl_mr(src.offset, src.base, dest); } + + void add32(RegisterID src, Address dest) + { + m_assembler.addl_rm(src, dest.offset, dest.base); + } void and32(RegisterID src, RegisterID dest) { @@ -102,6 +108,16 @@ public: m_assembler.andl_ir(imm.m_value, dest); } + void and32(RegisterID src, Address dest) + { + m_assembler.andl_rm(src, dest.offset, dest.base); + } + + void and32(Address src, RegisterID dest) + { + m_assembler.andl_mr(src.offset, src.base, dest); + } + void and32(Imm32 imm, Address address) { m_assembler.andl_im(imm.m_value, address.offset, address.base); @@ -116,20 +132,20 @@ public: { // On x86 we can only shift by ecx; if asked to shift by another register we'll // need rejig the shift amount into ecx first, and restore the registers afterwards. - if (shift_amount != X86::ecx) { - swap(shift_amount, X86::ecx); + if (shift_amount != X86Registers::ecx) { + swap(shift_amount, X86Registers::ecx); // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx" if (dest == shift_amount) - m_assembler.shll_CLr(X86::ecx); + m_assembler.shll_CLr(X86Registers::ecx); // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx" - else if (dest == X86::ecx) + else if (dest == X86Registers::ecx) m_assembler.shll_CLr(shift_amount); // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx" else m_assembler.shll_CLr(dest); - swap(shift_amount, X86::ecx); + swap(shift_amount, X86Registers::ecx); } else m_assembler.shll_CLr(dest); } @@ -138,16 +154,36 @@ public: { m_assembler.imull_rr(src, dest); } + + void mul32(Address src, RegisterID dest) + { + m_assembler.imull_mr(src.offset, src.base, dest); + } void mul32(Imm32 imm, RegisterID src, RegisterID dest) { m_assembler.imull_i32r(src, imm.m_value, dest); } - + + void neg32(RegisterID srcDest) + { + m_assembler.negl_r(srcDest); + } + + void neg32(Address srcDest) + { + m_assembler.negl_m(srcDest.offset, srcDest.base); + } + void not32(RegisterID srcDest) { m_assembler.notl_r(srcDest); } + + void not32(Address srcDest) + { + m_assembler.notl_m(srcDest.offset, srcDest.base); + } void or32(RegisterID src, RegisterID dest) { @@ -159,6 +195,16 @@ public: m_assembler.orl_ir(imm.m_value, dest); } + void or32(RegisterID src, Address dest) + { + m_assembler.orl_rm(src, dest.offset, dest.base); + } + + void or32(Address src, RegisterID dest) + { + m_assembler.orl_mr(src.offset, src.base, dest); + } + void or32(Imm32 imm, Address address) { m_assembler.orl_im(imm.m_value, address.offset, address.base); @@ -168,20 +214,20 @@ public: { // On x86 we can only shift by ecx; if asked to shift by another register we'll // need rejig the shift amount into ecx first, and restore the registers afterwards. - if (shift_amount != X86::ecx) { - swap(shift_amount, X86::ecx); + if (shift_amount != X86Registers::ecx) { + swap(shift_amount, X86Registers::ecx); // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx" if (dest == shift_amount) - m_assembler.sarl_CLr(X86::ecx); + m_assembler.sarl_CLr(X86Registers::ecx); // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx" - else if (dest == X86::ecx) + else if (dest == X86Registers::ecx) m_assembler.sarl_CLr(shift_amount); // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx" else m_assembler.sarl_CLr(dest); - swap(shift_amount, X86::ecx); + swap(shift_amount, X86Registers::ecx); } else m_assembler.sarl_CLr(dest); } @@ -211,14 +257,35 @@ public: m_assembler.subl_mr(src.offset, src.base, dest); } + void sub32(RegisterID src, Address dest) + { + m_assembler.subl_rm(src, dest.offset, dest.base); + } + + void xor32(RegisterID src, RegisterID dest) { m_assembler.xorl_rr(src, dest); } - void xor32(Imm32 imm, RegisterID srcDest) + void xor32(Imm32 imm, Address dest) { - m_assembler.xorl_ir(imm.m_value, srcDest); + m_assembler.xorl_im(imm.m_value, dest.offset, dest.base); + } + + void xor32(Imm32 imm, RegisterID dest) + { + m_assembler.xorl_ir(imm.m_value, dest); + } + + void xor32(RegisterID src, Address dest) + { + m_assembler.xorl_rm(src, dest.offset, dest.base); + } + + void xor32(Address src, RegisterID dest) + { + m_assembler.xorl_mr(src.offset, src.base, dest); } @@ -300,6 +367,18 @@ public: m_assembler.addsd_mr(src.offset, src.base, dest); } + void divDouble(FPRegisterID src, FPRegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.divsd_rr(src, dest); + } + + void divDouble(Address src, FPRegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.divsd_mr(src.offset, src.base, dest); + } + void subDouble(FPRegisterID src, FPRegisterID dest) { ASSERT(isSSE2Present()); @@ -330,6 +409,11 @@ public: m_assembler.cvtsi2sd_rr(src, dest); } + void convertInt32ToDouble(Address src, FPRegisterID dest) + { + m_assembler.cvtsi2sd_mr(src.offset, src.base, dest); + } + Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) { ASSERT(isSSE2Present()); @@ -337,6 +421,12 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + Jump branchDouble(DoubleCondition cond, FPRegisterID left, Address right) + { + m_assembler.ucomisd_mr(right.offset, right.base, left); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + // Truncates 'src' to an integer, and places the resulting 'dest'. // If the result is not representable as a 32 bit value, branch. // May also branch for some values that are representable in 32 bits @@ -348,6 +438,12 @@ public: return branch32(Equal, dest, Imm32(0x80000000)); } + void zeroDouble(FPRegisterID srcDest) + { + ASSERT(isSSE2Present()); + m_assembler.xorpd_rr(srcDest, srcDest); + } + // Stack manipulation operations: // @@ -397,15 +493,13 @@ public: { // Note: on 64-bit this is is a full register move; perhaps it would be // useful to have separate move32 & movePtr, with move32 zero extending? - m_assembler.movq_rr(src, dest); + if (src != dest) + m_assembler.movq_rr(src, dest); } void move(ImmPtr imm, RegisterID dest) { - if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr())) - m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest); - else - m_assembler.movq_i64r(imm.asIntptr(), dest); + m_assembler.movq_i64r(imm.asIntptr(), dest); } void swap(RegisterID reg1, RegisterID reg2) @@ -605,12 +699,40 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + Jump branchAdd32(Condition cond, Imm32 src, Address dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + add32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchAdd32(Condition cond, RegisterID src, Address dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + add32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchAdd32(Condition cond, Address src, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + add32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + Jump branchMul32(Condition cond, RegisterID src, RegisterID dest) { ASSERT(cond == Overflow); mul32(src, dest); return Jump(m_assembler.jCC(x86Condition(cond))); } + + Jump branchMul32(Condition cond, Address src, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + mul32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest) { @@ -632,7 +754,35 @@ public: sub32(imm, dest); return Jump(m_assembler.jCC(x86Condition(cond))); } - + + Jump branchSub32(Condition cond, Imm32 imm, Address dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + sub32(imm, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchSub32(Condition cond, RegisterID src, Address dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + sub32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchSub32(Condition cond, Address src, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); + sub32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchOr32(Condition cond, RegisterID src, RegisterID dest) + { + ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); + or32(src, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + // Miscellaneous operations: @@ -661,6 +811,27 @@ public: m_assembler.ret(); } + void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest) + { + m_assembler.cmpl_rr(right, left); + m_assembler.setCC_r(x86Condition(cond), dest); + } + + void set8(Condition cond, Address left, RegisterID right, RegisterID dest) + { + m_assembler.cmpl_mr(left.offset, left.base, right); + m_assembler.setCC_r(x86Condition(cond), dest); + } + + void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest) + { + if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) + m_assembler.testl_rr(left, left); + else + m_assembler.cmpl_ir(right.m_value, left); + m_assembler.setCC_r(x86Condition(cond), dest); + } + void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) { m_assembler.cmpl_rr(right, left); @@ -682,6 +853,16 @@ public: // The mask should be optional... paerhaps the argument order should be // dest-src, operations always have a dest? ... possibly not true, considering // asm ops like test, or pseudo ops like pop(). + + void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest) + { + if (mask.m_value == -1) + m_assembler.cmpl_im(0, address.offset, address.base); + else + m_assembler.testl_i32m(mask.m_value, address.offset, address.base); + m_assembler.setCC_r(x86Condition(cond), dest); + } + void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest) { if (mask.m_value == -1) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h index df0090a..0f95fe6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h @@ -38,7 +38,7 @@ namespace JSC { class MacroAssemblerX86_64 : public MacroAssemblerX86Common { protected: - static const X86::RegisterID scratchRegister = X86::r11; + static const X86Registers::RegisterID scratchRegister = X86Registers::r11; public: static const Scale ScalePtr = TimesEight; @@ -50,6 +50,8 @@ public: using MacroAssemblerX86Common::load32; using MacroAssemblerX86Common::store32; using MacroAssemblerX86Common::call; + using MacroAssemblerX86Common::loadDouble; + using MacroAssemblerX86Common::convertInt32ToDouble; void add32(Imm32 imm, AbsoluteAddress address) { @@ -77,21 +79,33 @@ public: void load32(void* address, RegisterID dest) { - if (dest == X86::eax) + if (dest == X86Registers::eax) m_assembler.movl_mEAX(address); else { - move(X86::eax, dest); + move(X86Registers::eax, dest); m_assembler.movl_mEAX(address); - swap(X86::eax, dest); + swap(X86Registers::eax, dest); } } + void loadDouble(void* address, FPRegisterID dest) + { + move(ImmPtr(address), scratchRegister); + loadDouble(scratchRegister, dest); + } + + void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) + { + move(Imm32(*static_cast<int32_t*>(src.m_ptr)), scratchRegister); + m_assembler.cvtsi2sd_rr(scratchRegister, dest); + } + void store32(Imm32 imm, void* address) { - move(X86::eax, scratchRegister); - move(imm, X86::eax); + move(X86Registers::eax, scratchRegister); + move(imm, X86Registers::eax); m_assembler.movl_EAXm(address); - move(scratchRegister, X86::eax); + move(scratchRegister, X86Registers::eax); } Call call() @@ -182,20 +196,20 @@ public: { // On x86 we can only shift by ecx; if asked to shift by another register we'll // need rejig the shift amount into ecx first, and restore the registers afterwards. - if (shift_amount != X86::ecx) { - swap(shift_amount, X86::ecx); + if (shift_amount != X86Registers::ecx) { + swap(shift_amount, X86Registers::ecx); // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx" if (dest == shift_amount) - m_assembler.sarq_CLr(X86::ecx); + m_assembler.sarq_CLr(X86Registers::ecx); // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx" - else if (dest == X86::ecx) + else if (dest == X86Registers::ecx) m_assembler.sarq_CLr(shift_amount); // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx" else m_assembler.sarq_CLr(dest); - swap(shift_amount, X86::ecx); + swap(shift_amount, X86Registers::ecx); } else m_assembler.sarq_CLr(dest); } @@ -244,12 +258,12 @@ public: void loadPtr(void* address, RegisterID dest) { - if (dest == X86::eax) + if (dest == X86Registers::eax) m_assembler.movq_mEAX(address); else { - move(X86::eax, dest); + move(X86Registers::eax, dest); m_assembler.movq_mEAX(address); - swap(X86::eax, dest); + swap(X86Registers::eax, dest); } } @@ -271,24 +285,19 @@ public: void storePtr(RegisterID src, void* address) { - if (src == X86::eax) + if (src == X86Registers::eax) m_assembler.movq_EAXm(address); else { - swap(X86::eax, src); + swap(X86Registers::eax, src); m_assembler.movq_EAXm(address); - swap(X86::eax, src); + swap(X86Registers::eax, src); } } void storePtr(ImmPtr imm, ImplicitAddress address) { - intptr_t ptr = imm.asIntptr(); - if (CAN_SIGN_EXTEND_32_64(ptr)) - m_assembler.movq_i32m(static_cast<int>(ptr), address.offset, address.base); - else { - move(imm, scratchRegister); - storePtr(scratchRegister, address); - } + move(imm, scratchRegister); + storePtr(scratchRegister, address); } DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address) @@ -325,17 +334,8 @@ public: Jump branchPtr(Condition cond, RegisterID left, ImmPtr right) { - intptr_t imm = right.asIntptr(); - if (CAN_SIGN_EXTEND_32_64(imm)) { - if (!imm) - m_assembler.testq_rr(left, left); - else - m_assembler.cmpq_ir(imm, left); - return Jump(m_assembler.jCC(x86Condition(cond))); - } else { - move(right, scratchRegister); - return branchPtr(cond, left, scratchRegister); - } + move(right, scratchRegister); + return branchPtr(cond, left, scratchRegister); } Jump branchPtr(Condition cond, RegisterID left, Address right) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h index 745bc60..cbbaaa5 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h @@ -38,12 +38,8 @@ namespace JSC { inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; } -#if PLATFORM(X86_64) -inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; } -inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; } -#endif -namespace X86 { +namespace X86Registers { typedef enum { eax, ecx, @@ -80,8 +76,8 @@ namespace X86 { class X86Assembler { public: - typedef X86::RegisterID RegisterID; - typedef X86::XMMRegisterID XMMRegisterID; + typedef X86Registers::RegisterID RegisterID; + typedef X86Registers::XMMRegisterID XMMRegisterID; typedef XMMRegisterID FPRegisterID; typedef enum { @@ -114,10 +110,12 @@ private: OP_OR_GvEv = 0x0B, OP_2BYTE_ESCAPE = 0x0F, OP_AND_EvGv = 0x21, + OP_AND_GvEv = 0x23, OP_SUB_EvGv = 0x29, OP_SUB_GvEv = 0x2B, PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E, OP_XOR_EvGv = 0x31, + OP_XOR_GvEv = 0x33, OP_CMP_EvGv = 0x39, OP_CMP_GvEv = 0x3B, #if PLATFORM(X86_64) @@ -169,6 +167,8 @@ private: OP2_ADDSD_VsdWsd = 0x58, OP2_MULSD_VsdWsd = 0x59, OP2_SUBSD_VsdWsd = 0x5C, + OP2_DIVSD_VsdWsd = 0x5E, + OP2_XORPD_VpdWpd = 0x57, OP2_MOVD_VdEd = 0x6E, OP2_MOVD_EdVd = 0x7E, OP2_JCC_rel32 = 0x80, @@ -205,6 +205,7 @@ private: GROUP3_OP_TEST = 0, GROUP3_OP_NOT = 2, + GROUP3_OP_NEG = 3, GROUP3_OP_IDIV = 7, GROUP5_OP_CALLN = 2, @@ -226,7 +227,6 @@ public: { } - void enableLatePatch() { } private: JmpSrc(int offset) : m_offset(offset) @@ -319,6 +319,11 @@ public: m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset); } + void addl_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset); + } + void addl_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -386,6 +391,16 @@ public: m_formatter.oneByteOp(OP_AND_EvGv, src, dst); } + void andl_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset); + } + + void andl_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset); + } + void andl_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -437,11 +452,26 @@ public: } #endif + void negl_r(RegisterID dst) + { + m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst); + } + + void negl_m(int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset); + } + void notl_r(RegisterID dst) { m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst); } + void notl_m(int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset); + } + void orl_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp(OP_OR_EvGv, src, dst); @@ -452,6 +482,11 @@ public: m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset); } + void orl_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset); + } + void orl_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -513,6 +548,11 @@ public: m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset); } + void subl_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset); + } + void subl_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -569,6 +609,27 @@ public: m_formatter.oneByteOp(OP_XOR_EvGv, src, dst); } + void xorl_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset); + } + + void xorl_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset); + } + + void xorl_im(int imm, int offset, RegisterID base) + { + if (CAN_SIGN_EXTEND_8_32(imm)) { + m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset); + m_formatter.immediate8(imm); + } else { + m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset); + m_formatter.immediate32(imm); + } + } + void xorl_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -649,7 +710,12 @@ public: { m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src); } - + + void imull_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset); + } + void imull_i32r(RegisterID src, int32_t value, RegisterID dst) { m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src); @@ -1048,7 +1114,7 @@ public: #else void movl_rm(RegisterID src, void* addr) { - if (src == X86::eax) + if (src == X86Registers::eax) movl_EAXm(addr); else m_formatter.oneByteOp(OP_MOV_EvGv, src, addr); @@ -1056,7 +1122,7 @@ public: void movl_mr(void* addr, RegisterID dst) { - if (dst == X86::eax) + if (dst == X86Registers::eax) movl_mEAX(addr); else m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); @@ -1154,6 +1220,11 @@ public: return m_formatter.immediateRel32(); } + JmpSrc jz() + { + return je(); + } + JmpSrc jl() { m_formatter.twoByteOp(jccRel32(ConditionL)); @@ -1246,6 +1317,20 @@ public: m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); } + void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset); + } + +#if !PLATFORM(X86_64) + void cvtsi2sd_mr(void* address, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address); + } +#endif + void cvttsd2si_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1284,6 +1369,14 @@ public: m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset); } +#if !PLATFORM(X86_64) + void movsd_mr(void* address, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address); + } +#endif + void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1321,6 +1414,30 @@ public: m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src); } + void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset); + } + + void divsd_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src); + } + + void divsd_mr(int offset, RegisterID base, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset); + } + + void xorpd_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src); + } + // Misc instructions: void int3() @@ -1605,6 +1722,16 @@ private: memoryModRM(reg, base, index, scale, offset); } +#if !PLATFORM(X86_64) + void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address) + { + m_buffer.ensureSpace(maxInstructionSize); + m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); + m_buffer.putByteUnchecked(opcode); + memoryModRM(reg, address); + } +#endif + #if PLATFORM(X86_64) // Quad-word-sized operands: // @@ -1761,23 +1888,23 @@ private: // Internals; ModRm and REX formatters. - static const RegisterID noBase = X86::ebp; - static const RegisterID hasSib = X86::esp; - static const RegisterID noIndex = X86::esp; + static const RegisterID noBase = X86Registers::ebp; + static const RegisterID hasSib = X86Registers::esp; + static const RegisterID noIndex = X86Registers::esp; #if PLATFORM(X86_64) - static const RegisterID noBase2 = X86::r13; - static const RegisterID hasSib2 = X86::r12; + static const RegisterID noBase2 = X86Registers::r13; + static const RegisterID hasSib2 = X86Registers::r12; // Registers r8 & above require a REX prefixe. inline bool regRequiresRex(int reg) { - return (reg >= X86::r8); + return (reg >= X86Registers::r8); } // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed). inline bool byteRegRequiresRex(int reg) { - return (reg >= X86::esp); + return (reg >= X86Registers::esp); } // Format a REX prefix byte. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp index 596d89a..7e5f6cf 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp @@ -33,6 +33,8 @@ #include "JIT.h" #include "JSValue.h" #include "Interpreter.h" +#include "JSFunction.h" +#include "JSStaticScopeObject.h" #include "Debugger.h" #include "BytecodeGenerator.h" #include <stdio.h> @@ -57,6 +59,9 @@ static UString escapeQuotes(const UString& str) static UString valueToSourceString(ExecState* exec, JSValue val) { + if (!val) + return "0"; + if (val.isString()) { UString result("\""); result += escapeQuotes(val.toString(exec)) + "\""; @@ -227,44 +232,44 @@ static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigne static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset) { - switch (stubInfo.opcodeID) { - case op_get_by_id_self: + switch (stubInfo.accessType) { + case access_get_by_id_self: printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str()); return; - case op_get_by_id_proto: + case access_get_by_id_proto: printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str()); return; - case op_get_by_id_chain: + case access_get_by_id_chain: printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str()); return; - case op_get_by_id_self_list: + case access_get_by_id_self_list: printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize); return; - case op_get_by_id_proto_list: + case access_get_by_id_proto_list: printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize); return; - case op_put_by_id_transition: + case access_put_by_id_transition: printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str()); return; - case op_put_by_id_replace: + case access_put_by_id_replace: printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str()); return; - case op_get_by_id: + case access_get_by_id: printf(" [%4d] %s\n", instructionOffset, "get_by_id"); return; - case op_put_by_id: + case access_put_by_id: printf(" [%4d] %s\n", instructionOffset, "put_by_id"); return; - case op_get_by_id_generic: + case access_get_by_id_generic: printf(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic"); return; - case op_put_by_id_generic: + case access_put_by_id_generic: printf(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic"); return; - case op_get_array_length: + case access_get_array_length: printf(" [%4d] %s\n", instructionOffset, "op_get_array_length"); return; - case op_get_string_length: + case access_get_string_length: printf(" [%4d] %s\n", instructionOffset, "op_get_string_length"); return; default: @@ -595,6 +600,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_div: { printBinaryOp(location, it, "div"); + ++it; break; } case op_mod: { @@ -739,13 +745,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); break; } - case op_resolve_func: { - int r0 = (++it)->u.operand; - int r1 = (++it)->u.operand; - int id0 = (++it)->u.operand; - printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); - break; - } case op_get_by_id: { printGetByIdOp(location, it, m_identifiers, "get_by_id"); break; @@ -1250,45 +1249,23 @@ void CodeBlock::dumpStatistics() #endif } -CodeBlock::CodeBlock(ScopeNode* ownerNode) - : m_numCalleeRegisters(0) - , m_numVars(0) - , m_numParameters(0) - , m_ownerNode(ownerNode) - , m_globalData(0) -#ifndef NDEBUG - , m_instructionCount(0) -#endif - , m_needsFullScopeChain(false) - , m_usesEval(false) - , m_usesArguments(false) - , m_isNumericCompareFunction(false) - , m_codeType(NativeCode) - , m_source(0) - , m_sourceOffset(0) - , m_exceptionInfo(0) -{ -#if DUMP_CODE_BLOCK_STATISTICS - liveCodeBlockSet.add(this); -#endif -} - -CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) +CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab) : m_numCalleeRegisters(0) , m_numVars(0) , m_numParameters(0) - , m_ownerNode(ownerNode) + , m_ownerExecutable(ownerExecutable) , m_globalData(0) #ifndef NDEBUG , m_instructionCount(0) #endif - , m_needsFullScopeChain(ownerNode->needsActivation()) - , m_usesEval(ownerNode->usesEval()) - , m_usesArguments(ownerNode->usesArguments()) + , m_needsFullScopeChain(ownerExecutable->needsActivation()) + , m_usesEval(ownerExecutable->usesEval()) + , m_usesArguments(ownerExecutable->usesArguments()) , m_isNumericCompareFunction(false) , m_codeType(codeType) , m_source(sourceProvider) , m_sourceOffset(sourceOffset) + , m_symbolTable(symTab) , m_exceptionInfo(new ExceptionInfo) { ASSERT(m_source); @@ -1325,20 +1302,23 @@ CodeBlock::~CodeBlock() if (Structure* structure = m_methodCallLinkInfos[i].cachedStructure) { structure->deref(); // Both members must be filled at the same time - ASSERT(m_methodCallLinkInfos[i].cachedPrototypeStructure); + ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure); m_methodCallLinkInfos[i].cachedPrototypeStructure->deref(); } } +#if ENABLE(JIT_OPTIMIZE_CALL) unlinkCallers(); #endif +#endif // !ENABLE(JIT) + #if DUMP_CODE_BLOCK_STATISTICS liveCodeBlockSet.remove(this); #endif } -#if ENABLE(JIT) +#if ENABLE(JIT_OPTIMIZE_CALL) void CodeBlock::unlinkCallers() { size_t size = m_linkedCallerList.size(); @@ -1353,7 +1333,6 @@ void CodeBlock::unlinkCallers() void CodeBlock::derefStructures(Instruction* vPC) const { - ASSERT(m_codeType != NativeCode); Interpreter* interpreter = m_globalData->interpreter; if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) { @@ -1399,7 +1378,6 @@ void CodeBlock::derefStructures(Instruction* vPC) const void CodeBlock::refStructures(Instruction* vPC) const { - ASSERT(m_codeType != NativeCode); Interpreter* interpreter = m_globalData->interpreter; if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) { @@ -1431,26 +1409,18 @@ void CodeBlock::refStructures(Instruction* vPC) const ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic)); } -void CodeBlock::mark() +void CodeBlock::markAggregate(MarkStack& markStack) { for (size_t i = 0; i < m_constantRegisters.size(); ++i) - if (!m_constantRegisters[i].marked()) - m_constantRegisters[i].mark(); - - for (size_t i = 0; i < m_functionExpressions.size(); ++i) - m_functionExpressions[i]->body()->mark(); - - if (m_rareData) { - for (size_t i = 0; i < m_rareData->m_functions.size(); ++i) - m_rareData->m_functions[i]->body()->mark(); - - m_rareData->m_evalCodeCache.mark(); - } + markStack.append(m_constantRegisters[i].jsValue()); + for (size_t i = 0; i < m_functionExprs.size(); ++i) + m_functionExprs[i]->markAggregate(markStack); + for (size_t i = 0; i < m_functionDecls.size(); ++i) + m_functionDecls[i]->markAggregate(markStack); } void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) { - ASSERT(m_codeType != NativeCode); if (m_exceptionInfo) return; @@ -1467,61 +1437,11 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) scopeChain = scopeChain->next; } - switch (m_codeType) { - case FunctionCode: { - FunctionBodyNode* ownerFunctionBodyNode = static_cast<FunctionBodyNode*>(m_ownerNode); - RefPtr<FunctionBodyNode> newFunctionBody = m_globalData->parser->reparse<FunctionBodyNode>(m_globalData, ownerFunctionBodyNode); - ASSERT(newFunctionBody); - newFunctionBody->finishParsing(ownerFunctionBodyNode->copyParameters(), ownerFunctionBodyNode->parameterCount()); - - m_globalData->scopeNodeBeingReparsed = newFunctionBody.get(); - - CodeBlock& newCodeBlock = newFunctionBody->bytecodeForExceptionInfoReparse(scopeChain, this); - ASSERT(newCodeBlock.m_exceptionInfo); - ASSERT(newCodeBlock.m_instructionCount == m_instructionCount); - -#if ENABLE(JIT) - JIT::compile(m_globalData, &newCodeBlock); - ASSERT(newFunctionBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size()); -#endif - - m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release()); - - m_globalData->scopeNodeBeingReparsed = 0; - - break; - } - case EvalCode: { - EvalNode* ownerEvalNode = static_cast<EvalNode*>(m_ownerNode); - RefPtr<EvalNode> newEvalBody = m_globalData->parser->reparse<EvalNode>(m_globalData, ownerEvalNode); - - m_globalData->scopeNodeBeingReparsed = newEvalBody.get(); - - EvalCodeBlock& newCodeBlock = newEvalBody->bytecodeForExceptionInfoReparse(scopeChain, this); - ASSERT(newCodeBlock.m_exceptionInfo); - ASSERT(newCodeBlock.m_instructionCount == m_instructionCount); - -#if ENABLE(JIT) - JIT::compile(m_globalData, &newCodeBlock); - ASSERT(newEvalBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size()); -#endif - - m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release()); - - m_globalData->scopeNodeBeingReparsed = 0; - - break; - } - default: - // CodeBlocks for Global code blocks are transient and therefore to not gain from - // from throwing out there exception information. - ASSERT_NOT_REACHED(); - } + m_exceptionInfo.set(m_ownerExecutable->reparseExceptionInfo(m_globalData, scopeChain, this)); } HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) { - ASSERT(m_codeType != NativeCode); ASSERT(bytecodeOffset < m_instructionCount); if (!m_rareData) @@ -1540,14 +1460,13 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset) { - ASSERT(m_codeType != NativeCode); ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); ASSERT(m_exceptionInfo); if (!m_exceptionInfo->m_lineInfo.size()) - return m_ownerNode->source().firstLine(); // Empty function + return m_ownerExecutable->source().firstLine(); // Empty function int low = 0; int high = m_exceptionInfo->m_lineInfo.size(); @@ -1560,13 +1479,12 @@ int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned byteco } if (!low) - return m_ownerNode->source().firstLine(); + return m_ownerExecutable->source().firstLine(); return m_exceptionInfo->m_lineInfo[low - 1].lineNumber; } int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset) { - ASSERT(m_codeType != NativeCode); ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); @@ -1606,7 +1524,6 @@ int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned b bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID) { - ASSERT(m_codeType != NativeCode); ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); @@ -1635,7 +1552,6 @@ bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsi #if ENABLE(JIT) bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex) { - ASSERT(m_codeType != NativeCode); ASSERT(bytecodeOffset < m_instructionCount); if (!m_rareData || !m_rareData->m_functionRegisterInfos.size()) @@ -1662,7 +1578,6 @@ bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& #if !ENABLE(JIT) bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset) { - ASSERT(m_codeType != NativeCode); if (m_globalResolveInstructions.isEmpty()) return false; @@ -1683,7 +1598,6 @@ bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOff #else bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) { - ASSERT(m_codeType != NativeCode); if (m_globalResolveInfos.isEmpty()) return false; @@ -1703,18 +1617,6 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) } #endif -#if ENABLE(JIT) -void CodeBlock::setJITCode(JITCode jitCode) -{ - ASSERT(m_codeType != NativeCode); - ownerNode()->setJITCode(jitCode); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_instructions.clear(); -#endif -} -#endif - void CodeBlock::shrinkToFit() { m_instructions.shrinkToFit(); @@ -1730,7 +1632,8 @@ void CodeBlock::shrinkToFit() #endif m_identifiers.shrinkToFit(); - m_functionExpressions.shrinkToFit(); + m_functionDecls.shrinkToFit(); + m_functionExprs.shrinkToFit(); m_constantRegisters.shrinkToFit(); if (m_exceptionInfo) { @@ -1741,7 +1644,6 @@ void CodeBlock::shrinkToFit() if (m_rareData) { m_rareData->m_exceptionHandlers.shrinkToFit(); - m_rareData->m_functions.shrinkToFit(); m_rareData->m_regexps.shrinkToFit(); m_rareData->m_immediateSwitchJumpTables.shrinkToFit(); m_rareData->m_characterSwitchJumpTables.shrinkToFit(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h index e9f2697..0163540 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h @@ -36,6 +36,7 @@ #include "JSGlobalObject.h" #include "JumpTable.h" #include "Nodes.h" +#include "PtrAndFlags.h" #include "RegExp.h" #include "UString.h" #include <wtf/FastAllocBase.h> @@ -54,9 +55,13 @@ static const int FirstConstantRegisterIndex = 0x40000000; namespace JSC { + enum HasSeenShouldRepatch { + hasSeenShouldRepatch + }; + class ExecState; - enum CodeType { GlobalCode, EvalCode, FunctionCode, NativeCode }; + enum CodeType { GlobalCode, EvalCode, FunctionCode }; static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); } @@ -105,25 +110,44 @@ namespace JSC { CodeLocationNearCall callReturnLocation; CodeLocationDataLabelPtr hotPathBegin; CodeLocationNearCall hotPathOther; - CodeBlock* ownerCodeBlock; + PtrAndFlags<CodeBlock, HasSeenShouldRepatch> ownerCodeBlock; CodeBlock* callee; unsigned position; void setUnlinked() { callee = 0; } bool isLinked() { return callee; } + + bool seenOnce() + { + return ownerCodeBlock.isFlagSet(hasSeenShouldRepatch); + } + + void setSeen() + { + ownerCodeBlock.setFlag(hasSeenShouldRepatch); + } }; struct MethodCallLinkInfo { MethodCallLinkInfo() : cachedStructure(0) - , cachedPrototypeStructure(0) { } + bool seenOnce() + { + return cachedPrototypeStructure.isFlagSet(hasSeenShouldRepatch); + } + + void setSeen() + { + cachedPrototypeStructure.setFlag(hasSeenShouldRepatch); + } + CodeLocationCall callReturnLocation; CodeLocationDataLabelPtr structureLabel; Structure* cachedStructure; - Structure* cachedPrototypeStructure; + PtrAndFlags<Structure, HasSeenShouldRepatch> cachedPrototypeStructure; }; struct FunctionRegisterInfo { @@ -224,17 +248,27 @@ namespace JSC { } #endif + struct ExceptionInfo : FastAllocBase { + Vector<ExpressionRangeInfo> m_expressionInfo; + Vector<LineInfo> m_lineInfo; + Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo; + +#if ENABLE(JIT) + Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector; +#endif + }; + class CodeBlock : public FastAllocBase { friend class JIT; + protected: + CodeBlock(ScriptExecutable* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable* symbolTable); public: - CodeBlock(ScopeNode* ownerNode); - CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset); - ~CodeBlock(); + virtual ~CodeBlock(); - void mark(); + void markAggregate(MarkStack&); void refStructures(Instruction* vPC) const; void derefStructures(Instruction* vPC) const; -#if ENABLE(JIT) +#if ENABLE(JIT_OPTIMIZE_CALL) void unlinkCallers(); #endif @@ -305,7 +339,7 @@ namespace JSC { unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress) { reparseForExceptionInfoIfNecessary(callFrame); - return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), ownerNode()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex; + return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), ownerExecutable()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex; } bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex); @@ -315,17 +349,19 @@ namespace JSC { bool isNumericCompareFunction() { return m_isNumericCompareFunction; } Vector<Instruction>& instructions() { return m_instructions; } + void discardBytecode() { m_instructions.clear(); } + #ifndef NDEBUG + unsigned instructionCount() { return m_instructionCount; } void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; } #endif #if ENABLE(JIT) - JITCode& getJITCode() { return ownerNode()->generatedJITCode(); } - void setJITCode(JITCode); - ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); } + JITCode& getJITCode() { return ownerExecutable()->generatedJITCode(); } + ExecutablePool* executablePool() { return ownerExecutable()->getExecutablePool(); } #endif - ScopeNode* ownerNode() const { return m_ownerNode; } + ScriptExecutable* ownerExecutable() const { return m_ownerExecutable; } void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; } @@ -341,8 +377,8 @@ namespace JSC { CodeType codeType() const { return m_codeType; } - SourceProvider* source() const { ASSERT(m_codeType != NativeCode); return m_source.get(); } - unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode); return m_sourceOffset; } + SourceProvider* source() const { return m_source.get(); } + unsigned sourceOffset() const { return m_sourceOffset; } size_t numberOfJumpTargets() const { return m_jumpTargets.size(); } void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); } @@ -380,6 +416,7 @@ namespace JSC { bool hasExceptionInfo() const { return m_exceptionInfo; } void clearExceptionInfo() { m_exceptionInfo.clear(); } + ExceptionInfo* extractExceptionInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo.release(); } void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); } void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); } @@ -404,13 +441,11 @@ namespace JSC { ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; } ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); } - unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; } - FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); } - - unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; } - FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); } - - bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); } + unsigned addFunctionDecl(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; } + FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); } + int numberOfFunctionDecls() { return m_functionDecls.size(); } + unsigned addFunctionExpr(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; } + FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); } unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; } RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); } @@ -431,9 +466,10 @@ namespace JSC { StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; } - SymbolTable& symbolTable() { return m_symbolTable; } + SymbolTable* symbolTable() { return m_symbolTable; } + SharedSymbolTable* sharedSymbolTable() { ASSERT(m_codeType == FunctionCode); return static_cast<SharedSymbolTable*>(m_symbolTable); } - EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode); createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; } + EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; } void shrinkToFit(); @@ -452,12 +488,11 @@ namespace JSC { void createRareDataIfNecessary() { - ASSERT(m_codeType != NativeCode); if (!m_rareData) m_rareData.set(new RareData); } - ScopeNode* m_ownerNode; + ScriptExecutable* m_ownerExecutable; JSGlobalData* m_globalData; Vector<Instruction> m_instructions; @@ -493,26 +528,17 @@ namespace JSC { // Constant Pool Vector<Identifier> m_identifiers; Vector<Register> m_constantRegisters; - Vector<RefPtr<FuncExprNode> > m_functionExpressions; - - SymbolTable m_symbolTable; + Vector<RefPtr<FunctionExecutable> > m_functionDecls; + Vector<RefPtr<FunctionExecutable> > m_functionExprs; - struct ExceptionInfo : FastAllocBase { - Vector<ExpressionRangeInfo> m_expressionInfo; - Vector<LineInfo> m_lineInfo; - Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo; + SymbolTable* m_symbolTable; -#if ENABLE(JIT) - Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector; -#endif - }; OwnPtr<ExceptionInfo> m_exceptionInfo; struct RareData : FastAllocBase { Vector<HandlerInfo> m_exceptionHandlers; // Rare Constants - Vector<RefPtr<FuncDeclNode> > m_functions; Vector<RefPtr<RegExp> > m_regexps; // Jump Tables @@ -532,16 +558,16 @@ namespace JSC { // Program code is not marked by any function, so we make the global object // responsible for marking it. - class ProgramCodeBlock : public CodeBlock { + class GlobalCodeBlock : public CodeBlock { public: - ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider) - : CodeBlock(ownerNode, codeType, sourceProvider, 0) + GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, JSGlobalObject* globalObject) + : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, &m_unsharedSymbolTable) , m_globalObject(globalObject) { m_globalObject->codeBlocks().add(this); } - ~ProgramCodeBlock() + ~GlobalCodeBlock() { if (m_globalObject) m_globalObject->codeBlocks().remove(this); @@ -551,20 +577,54 @@ namespace JSC { private: JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool. + SymbolTable m_unsharedSymbolTable; + }; + + class ProgramCodeBlock : public GlobalCodeBlock { + public: + ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider) + : GlobalCodeBlock(ownerExecutable, codeType, sourceProvider, 0, globalObject) + { + } }; - class EvalCodeBlock : public ProgramCodeBlock { + class EvalCodeBlock : public GlobalCodeBlock { public: - EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth) - : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider) + EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth) + : GlobalCodeBlock(ownerExecutable, EvalCode, sourceProvider, 0, globalObject) , m_baseScopeDepth(baseScopeDepth) { } int baseScopeDepth() const { return m_baseScopeDepth; } + const Identifier& variable(unsigned index) { return m_variables[index]; } + unsigned numVariables() { return m_variables.size(); } + void adoptVariables(Vector<Identifier>& variables) + { + ASSERT(m_variables.isEmpty()); + m_variables.swap(variables); + } + private: int m_baseScopeDepth; + Vector<Identifier> m_variables; + }; + + class FunctionCodeBlock : public CodeBlock { + public: + // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new + // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared + // symbol table, so we just pass as a raw pointer with a ref count of 1. We then manually deref + // in the destructor. + FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) + : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, new SharedSymbolTable) + { + } + ~FunctionCodeBlock() + { + sharedSymbolTable()->deref(); + } }; inline Register& ExecState::r(int index) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h index f0ce73e..0e1fb1e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h @@ -29,6 +29,7 @@ #ifndef EvalCodeCache_h #define EvalCodeCache_h +#include "Executable.h" #include "JSGlobalObject.h" #include "Nodes.h" #include "Parser.h" @@ -41,44 +42,33 @@ namespace JSC { class EvalCodeCache { public: - PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + PassRefPtr<EvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) { - RefPtr<EvalNode> evalNode; + RefPtr<EvalExecutable> evalExecutable; if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) - evalNode = m_cacheMap.get(evalSource.rep()); + evalExecutable = m_cacheMap.get(evalSource.rep()); - if (!evalNode) { - int errorLine; - UString errorMessage; - - SourceCode source = makeSource(evalSource); - evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage); - if (evalNode) { - if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) - m_cacheMap.set(evalSource.rep(), evalNode); - } else { - exceptionValue = Error::create(exec, SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0); + if (!evalExecutable) { + evalExecutable = EvalExecutable::create(makeSource(evalSource)); + exceptionValue = evalExecutable->compile(exec, scopeChain); + if (exceptionValue) return 0; - } + + if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + m_cacheMap.set(evalSource.rep(), evalExecutable); } - return evalNode.release(); + return evalExecutable.release(); } bool isEmpty() const { return m_cacheMap.isEmpty(); } - void mark() - { - EvalCacheMap::iterator end = m_cacheMap.end(); - for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr) - ptr->second->mark(); - } private: static const int maxCacheableSourceLength = 256; static const int maxCacheEntries = 64; - typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalNode> > EvalCacheMap; + typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalExecutable> > EvalCacheMap; EvalCacheMap m_cacheMap; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h index 594c4dd..bc2de19 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h @@ -54,7 +54,7 @@ namespace JSC { class StructureChain; // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream. - struct PolymorphicAccessStructureList { + struct PolymorphicAccessStructureList : FastAllocBase { struct PolymorphicStubInfo { bool isChain; PolymorphicAccessStructureListStubRoutineType stubRoutine; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h index 4baa0be..cf50442 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h @@ -67,7 +67,7 @@ namespace JSC { macro(op_negate, 3) \ macro(op_add, 5) \ macro(op_mul, 5) \ - macro(op_div, 4) \ + macro(op_div, 5) \ macro(op_mod, 4) \ macro(op_sub, 5) \ \ @@ -98,7 +98,6 @@ namespace JSC { macro(op_put_global_var, 4) \ macro(op_resolve_base, 3) \ macro(op_resolve_with_base, 4) \ - macro(op_resolve_func, 4) \ macro(op_get_by_id, 8) \ macro(op_get_by_id_self, 8) \ macro(op_get_by_id_self_list, 8) \ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp index 8651723..8d0faa1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp @@ -197,7 +197,7 @@ void SamplingTool::doRun() #if ENABLE(CODEBLOCK_SAMPLING) if (CodeBlock* codeBlock = sample.codeBlock()) { MutexLocker locker(m_scopeSampleMapMutex); - ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode()); + ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); ASSERT(record); record->sample(codeBlock, sample.vPC()); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h index fa95603..1a3f7cf 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h @@ -136,7 +136,7 @@ namespace JSC { class SamplingTool { public: - friend class CallRecord; + friend struct CallRecord; friend class HostCallRecord; #if ENABLE(OPCODE_SAMPLING) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp index bf3fdc4..018d832 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp @@ -31,44 +31,44 @@ namespace JSC { #if ENABLE(JIT) void StructureStubInfo::deref() { - switch (opcodeID) { - case op_get_by_id_self: + switch (accessType) { + case access_get_by_id_self: u.getByIdSelf.baseObjectStructure->deref(); return; - case op_get_by_id_proto: + case access_get_by_id_proto: u.getByIdProto.baseObjectStructure->deref(); u.getByIdProto.prototypeStructure->deref(); return; - case op_get_by_id_chain: + case access_get_by_id_chain: u.getByIdChain.baseObjectStructure->deref(); u.getByIdChain.chain->deref(); return; - case op_get_by_id_self_list: { + case access_get_by_id_self_list: { PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList; polymorphicStructures->derefStructures(u.getByIdSelfList.listSize); delete polymorphicStructures; return; } - case op_get_by_id_proto_list: { + case access_get_by_id_proto_list: { PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList; polymorphicStructures->derefStructures(u.getByIdProtoList.listSize); delete polymorphicStructures; return; } - case op_put_by_id_transition: + case access_put_by_id_transition: u.putByIdTransition.previousStructure->deref(); u.putByIdTransition.structure->deref(); u.putByIdTransition.chain->deref(); return; - case op_put_by_id_replace: + case access_put_by_id_replace: u.putByIdReplace.baseObjectStructure->deref(); return; - case op_get_by_id: - case op_put_by_id: - case op_get_by_id_generic: - case op_put_by_id_generic: - case op_get_array_length: - case op_get_string_length: + case access_get_by_id: + case access_put_by_id: + case access_get_by_id_generic: + case access_put_by_id_generic: + case access_get_array_length: + case access_get_string_length: // These instructions don't ref their Structures. return; default: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h index 95dd266..8e2c489 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h @@ -35,15 +35,32 @@ namespace JSC { + enum AccessType { + access_get_by_id_self, + access_get_by_id_proto, + access_get_by_id_chain, + access_get_by_id_self_list, + access_get_by_id_proto_list, + access_put_by_id_transition, + access_put_by_id_replace, + access_get_by_id, + access_put_by_id, + access_get_by_id_generic, + access_put_by_id_generic, + access_get_array_length, + access_get_string_length, + }; + struct StructureStubInfo { - StructureStubInfo(OpcodeID opcodeID) - : opcodeID(opcodeID) + StructureStubInfo(AccessType accessType) + : accessType(accessType) + , seen(false) { } void initGetByIdSelf(Structure* baseObjectStructure) { - opcodeID = op_get_by_id_self; + accessType = access_get_by_id_self; u.getByIdSelf.baseObjectStructure = baseObjectStructure; baseObjectStructure->ref(); @@ -51,7 +68,7 @@ namespace JSC { void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure) { - opcodeID = op_get_by_id_proto; + accessType = access_get_by_id_proto; u.getByIdProto.baseObjectStructure = baseObjectStructure; baseObjectStructure->ref(); @@ -62,7 +79,7 @@ namespace JSC { void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain) { - opcodeID = op_get_by_id_chain; + accessType = access_get_by_id_chain; u.getByIdChain.baseObjectStructure = baseObjectStructure; baseObjectStructure->ref(); @@ -73,7 +90,7 @@ namespace JSC { void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize) { - opcodeID = op_get_by_id_self_list; + accessType = access_get_by_id_self_list; u.getByIdProtoList.structureList = structureList; u.getByIdProtoList.listSize = listSize; @@ -81,7 +98,7 @@ namespace JSC { void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize) { - opcodeID = op_get_by_id_proto_list; + accessType = access_get_by_id_proto_list; u.getByIdProtoList.structureList = structureList; u.getByIdProtoList.listSize = listSize; @@ -91,7 +108,7 @@ namespace JSC { void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain) { - opcodeID = op_put_by_id_transition; + accessType = access_put_by_id_transition; u.putByIdTransition.previousStructure = previousStructure; previousStructure->ref(); @@ -105,7 +122,7 @@ namespace JSC { void initPutByIdReplace(Structure* baseObjectStructure) { - opcodeID = op_put_by_id_replace; + accessType = access_put_by_id_replace; u.putByIdReplace.baseObjectStructure = baseObjectStructure; baseObjectStructure->ref(); @@ -113,7 +130,19 @@ namespace JSC { void deref(); - OpcodeID opcodeID; + bool seenOnce() + { + return seen; + } + + void setSeen() + { + seen = true; + } + + int accessType : 31; + int seen : 1; + union { struct { Structure* baseObjectStructure; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 711beb4..74bf4f8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -256,15 +256,15 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d m_nextGlobalIndex -= symbolTable->size(); for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i]; - globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property. - emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl); + FunctionBodyNode* function = functionStack[i]; + globalObject->removeDirect(function->ident()); // Make sure our new function is not shadowed by an old property. + emitNewFunction(addGlobalVar(function->ident(), false), function); } Vector<RegisterID*, 32> newVars; for (size_t i = 0; i < varStack.size(); ++i) - if (!globalObject->hasProperty(exec, varStack[i].first)) - newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant)); + if (!globalObject->hasProperty(exec, *varStack[i].first)) + newVars.append(addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant)); preserveLastVar(); @@ -272,16 +272,16 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d emitLoad(newVars[i], jsUndefined()); } else { for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i]; - globalObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, scopeChain.node()), DontDelete); + FunctionBodyNode* function = functionStack[i]; + globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(function), scopeChain.node()), DontDelete); } for (size_t i = 0; i < varStack.size(); ++i) { - if (globalObject->hasProperty(exec, varStack[i].first)) + if (globalObject->hasProperty(exec, *varStack[i].first)) continue; int attributes = DontDelete; if (varStack[i].second & DeclarationStacks::IsConstant) attributes |= ReadOnly; - globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes); + globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes); } preserveLastVar(); @@ -327,7 +327,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug } else emitOpcode(op_enter); - if (usesArguments) { + if (usesArguments) { emitOpcode(op_init_arguments); // The debugger currently retrieves the arguments object from an activation rather than pulling @@ -339,18 +339,18 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack(); for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i]; - const Identifier& ident = funcDecl->m_ident; + FunctionBodyNode* function = functionStack[i]; + const Identifier& ident = function->ident(); m_functions.add(ident.ustring().rep()); - emitNewFunction(addVar(ident, false), funcDecl); + emitNewFunction(addVar(ident, false), function); } const DeclarationStacks::VarStack& varStack = functionBody->varStack(); for (size_t i = 0; i < varStack.size(); ++i) - addVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant); + addVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant); - const Identifier* parameters = functionBody->parameters(); - size_t parameterCount = functionBody->parameterCount(); + FunctionParameters& parameters = *functionBody->parameters(); + size_t parameterCount = parameters.size(); m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1; m_parameters.grow(1 + parameterCount); // reserve space for "this" @@ -397,6 +397,18 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge codeBlock->setGlobalData(m_globalData); m_codeBlock->m_numParameters = 1; // Allocate space for "this" + const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); + for (size_t i = 0; i < functionStack.size(); ++i) + m_codeBlock->addFunctionDecl(makeFunction(functionStack[i])); + + const DeclarationStacks::VarStack& varStack = evalNode->varStack(); + unsigned numVariables = varStack.size(); + Vector<Identifier> variables; + variables.reserveCapacity(numVariables); + for (size_t i = 0; i < numVariables; ++i) + variables.append(*varStack[i].first); + codeBlock->adoptVariables(variables); + preserveLastVar(); } @@ -470,7 +482,8 @@ RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident) return 0; SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); - ASSERT(!entry.isNull()); + if (entry.isNull()) + return 0; return ®isterFor(entry.getIndex()); } @@ -765,18 +778,6 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond return target; } -unsigned BytecodeGenerator::addConstant(FuncDeclNode* n) -{ - // No need to explicitly unique function body nodes -- they're unique already. - return m_codeBlock->addFunction(n); -} - -unsigned BytecodeGenerator::addConstant(FuncExprNode* n) -{ - // No need to explicitly unique function expression nodes -- they're unique already. - return m_codeBlock->addFunctionExpression(n); -} - unsigned BytecodeGenerator::addConstant(const Identifier& ident) { UString::Rep* rep = ident.ustring().rep(); @@ -861,9 +862,8 @@ RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, instructions().append(src2->index()); if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor || - opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) { + opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div) instructions().append(types.toInt()); - } return dst; } @@ -1183,15 +1183,6 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register return baseDst; } -RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property) -{ - emitOpcode(op_resolve_func); - instructions().append(baseDst->index()); - instructions().append(funcDst->index()); - instructions().append(addConstant(property)); - return baseDst; -} - void BytecodeGenerator::emitMethodCheck() { emitOpcode(op_method_check); @@ -1200,7 +1191,7 @@ void BytecodeGenerator::emitMethodCheck() RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property) { #if ENABLE(JIT) - m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id)); + m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id)); #else m_codeBlock->addPropertyAccessInstruction(instructions().size()); #endif @@ -1219,7 +1210,7 @@ RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, co RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value) { #if ENABLE(JIT) - m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id)); + m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id)); #else m_codeBlock->addPropertyAccessInstruction(instructions().size()); #endif @@ -1323,11 +1314,13 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen return dst; } -RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n) +RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function) { + unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function)); + emitOpcode(op_new_func); instructions().append(dst->index()); - instructions().append(addConstant(n)); + instructions().append(index); return dst; } @@ -1342,9 +1335,12 @@ RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp) RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n) { + FunctionBodyNode* function = n->body(); + unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function)); + emitOpcode(op_new_func_exp); instructions().append(r0->index()); - instructions().append(addConstant(n)); + instructions().append(index); return r0; } @@ -1806,6 +1802,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, emitOpcode(op_jsr); instructions().append(retAddrDst->index()); instructions().append(finally->offsetFrom(instructions().size())); + emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. return finally; } @@ -1815,7 +1812,7 @@ void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc) instructions().append(retAddrSrc->index()); } -void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value) +void BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value) { ControlFlowContext context; context.isFinallyBlock = false; @@ -1859,7 +1856,6 @@ static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t ASSERT(node->isNumber()); double value = static_cast<NumberNode*>(node)->value(); int32_t key = static_cast<int32_t>(value); - ASSERT(JSValue::makeInt32Fast(key) && (JSValue::makeInt32Fast(key).getInt32Fast() == value)); ASSERT(key == value); ASSERT(key >= min); ASSERT(key <= max); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h index f7f7e1c..935787c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -61,7 +61,7 @@ namespace JSC { FinallyContext finallyContext; }; - class BytecodeGenerator : public WTF::FastAllocBase { + class BytecodeGenerator : public FastAllocBase { public: typedef DeclarationStacks::VarStack VarStack; typedef DeclarationStacks::FunctionStack FunctionStack; @@ -254,7 +254,7 @@ namespace JSC { RegisterID* emitNewObject(RegisterID* dst); RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision - RegisterID* emitNewFunction(RegisterID* dst, FuncDeclNode* func); + RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body); RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func); RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp); @@ -276,7 +276,6 @@ namespace JSC { RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property); RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property); - RegisterID* emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property); void emitMethodCheck(); @@ -319,7 +318,7 @@ namespace JSC { RegisterID* emitCatch(RegisterID*, Label* start, Label* end); void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); } RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue message); - void emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value); + void emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value); RegisterID* emitPushScope(RegisterID* scope); void emitPopScope(); @@ -355,7 +354,7 @@ namespace JSC { PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope); - typedef HashMap<EncodedJSValue, unsigned, PtrHash<EncodedJSValue>, JSValueHashTraits> JSValueMap; + typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap; struct IdentifierMapIndexHashTraits { typedef int TraitType; @@ -414,12 +413,15 @@ namespace JSC { return m_globals[-index - 1]; } - unsigned addConstant(FuncDeclNode*); - unsigned addConstant(FuncExprNode*); unsigned addConstant(const Identifier&); RegisterID* addConstantValue(JSValue); unsigned addRegExp(RegExp*); + PassRefPtr<FunctionExecutable> makeFunction(FunctionBodyNode* body) + { + return FunctionExecutable::create(body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + } + Vector<Instruction>& instructions() { return m_codeBlock->instructions(); } SymbolTable& symbolTable() { return *m_symbolTable; } @@ -446,12 +448,12 @@ namespace JSC { RegisterID m_thisRegister; RegisterID m_argumentsRegister; int m_activationRegisterIndex; - WTF::SegmentedVector<RegisterID, 32> m_constantPoolRegisters; - WTF::SegmentedVector<RegisterID, 32> m_calleeRegisters; - WTF::SegmentedVector<RegisterID, 32> m_parameters; - WTF::SegmentedVector<RegisterID, 32> m_globals; - WTF::SegmentedVector<Label, 32> m_labels; - WTF::SegmentedVector<LabelScope, 8> m_labelScopes; + SegmentedVector<RegisterID, 32> m_constantPoolRegisters; + SegmentedVector<RegisterID, 32> m_calleeRegisters; + SegmentedVector<RegisterID, 32> m_parameters; + SegmentedVector<RegisterID, 32> m_globals; + SegmentedVector<Label, 32> m_labels; + SegmentedVector<LabelScope, 8> m_labelScopes; RefPtr<RegisterID> m_lastVar; int m_finallyDepth; int m_dynamicScopeDepth; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/config.h b/src/3rdparty/javascriptcore/JavaScriptCore/config.h index 6681761..5e70265 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/config.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/config.h @@ -25,6 +25,7 @@ #include <wtf/Platform.h> +#if !defined(JS_EXPORTDATA) #if PLATFORM(WIN_OS) && !defined(BUILDING_WX__) && !COMPILER(GCC) #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF) #define JS_EXPORTDATA __declspec(dllexport) @@ -34,6 +35,7 @@ #else #define JS_EXPORTDATA #endif +#endif #if PLATFORM(WIN_OS) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp index 7d791e7..61167d4 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp @@ -22,16 +22,16 @@ #include "config.h" #include "Debugger.h" -#include "JSGlobalObject.h" +#include "CollectorHeapIterator.h" +#include "Error.h" #include "Interpreter.h" +#include "JSFunction.h" +#include "JSGlobalObject.h" #include "Parser.h" +#include "Protect.h" namespace JSC { -Debugger::Debugger() -{ -} - Debugger::~Debugger() { HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end(); @@ -53,18 +53,59 @@ void Debugger::detach(JSGlobalObject* globalObject) globalObject->setDebugger(0); } +void Debugger::recompileAllJSFunctions(JSGlobalData* globalData) +{ + // If JavaScript is running, it's not safe to recompile, since we'll end + // up throwing away code that is live on the stack. + ASSERT(!globalData->dynamicGlobalObject); + if (globalData->dynamicGlobalObject) + return; + + typedef HashSet<FunctionExecutable*> FunctionExecutableSet; + typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap; + + FunctionExecutableSet functionExecutables; + SourceProviderMap sourceProviders; + + Heap::iterator heapEnd = globalData->heap.primaryHeapEnd(); + for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) { + if (!(*it)->inherits(&JSFunction::info)) + continue; + + JSFunction* function = asFunction(*it); + if (function->executable()->isHostFunction()) + continue; + + FunctionExecutable* executable = function->jsExecutable(); + + // Check if the function is already in the set - if so, + // we've already retranslated it, nothing to do here. + if (!functionExecutables.add(executable).second) + continue; + + ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec(); + executable->recompile(exec); + if (function->scope().globalObject()->debugger() == this) + sourceProviders.add(executable->source().provider(), exec); + } + + // Call sourceParsed() after reparsing all functions because it will execute + // JavaScript in the inspector. + SourceProviderMap::const_iterator end = sourceProviders.end(); + for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter) + sourceParsed(iter->second, SourceCode(iter->first), -1, 0); +} + JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject) { CallFrame* globalCallFrame = globalObject->globalExec(); - int errLine; - UString errMsg; - SourceCode source = makeSource(script); - RefPtr<EvalNode> evalNode = globalObject->globalData()->parser->parse<EvalNode>(globalCallFrame, globalObject->debugger(), source, &errLine, &errMsg); - if (!evalNode) - return Error::create(globalCallFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); + EvalExecutable eval(makeSource(script)); + JSObject* error = eval.compile(globalCallFrame, globalCallFrame->scopeChain()); + if (error) + return error; - return globalObject->globalData()->interpreter->execute(evalNode.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception); + return globalObject->globalData()->interpreter->execute(&eval, globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h index 1ed39ec..8072162 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,18 +23,19 @@ #define Debugger_h #include <debugger/DebuggerCallFrame.h> -#include "Protect.h" +#include <wtf/HashSet.h> namespace JSC { class ExecState; + class JSGlobalData; class JSGlobalObject; + class JSValue; class SourceCode; class UString; class Debugger { public: - Debugger(); virtual ~Debugger(); void attach(JSGlobalObject*); @@ -87,22 +88,23 @@ namespace JSC { #endif #endif - virtual void sourceParsed(ExecState*, const SourceCode&, int errorLine, const UString& errorMsg) = 0; - virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0; - virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineno, int column) = 0; - virtual void callEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0; - virtual void returnEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0; + virtual void sourceParsed(ExecState*, const SourceCode&, int errorLineNumber, const UString& errorMessage) = 0; + virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; + virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int column) = 0; + virtual void callEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; + virtual void returnEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; - virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0; - virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0; - virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t sourceID, int lineno, int column) = 0; + virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; + virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; + virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int column) = 0; + + void recompileAllJSFunctions(JSGlobalData*); private: HashSet<JSGlobalObject*> m_globalObjects; }; - // This method exists only for backwards compatibility with existing - // WebScriptDebugger clients + // This function exists only for backwards compatibility with existing WebScriptDebugger clients. JSValue evaluateInGlobalCallFrame(const UString&, JSValue& exception, JSGlobalObject*); } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp index c1815c8..fa41374 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -38,11 +38,12 @@ DebuggerActivation::DebuggerActivation(JSObject* activation) m_activation = static_cast<JSActivation*>(activation); } -void DebuggerActivation::mark() +void DebuggerActivation::markChildren(MarkStack& markStack) { - JSObject::mark(); - if (m_activation && !m_activation->marked()) - m_activation->mark(); + JSObject::markChildren(markStack); + + if (m_activation) + markStack.append(m_activation); } UString DebuggerActivation::className() const @@ -70,9 +71,9 @@ bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& prope return m_activation->deleteProperty(exec, propertyName, checkDontDelete); } -void DebuggerActivation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { - m_activation->getPropertyNames(exec, propertyNames, listedAttributes); + m_activation->getPropertyNames(exec, propertyNames); } bool DebuggerActivation::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const @@ -80,14 +81,14 @@ bool DebuggerActivation::getPropertyAttributes(JSC::ExecState* exec, const Ident return m_activation->getPropertyAttributes(exec, propertyName, attributes); } -void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { - m_activation->defineGetter(exec, propertyName, getterFunction); + m_activation->defineGetter(exec, propertyName, getterFunction, attributes); } -void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { - m_activation->defineSetter(exec, propertyName, setterFunction); + m_activation->defineSetter(exec, propertyName, setterFunction, attributes); } JSValue DebuggerActivation::lookupGetter(ExecState* exec, const Identifier& propertyName) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h index 7c9f7d1..9bb1acd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -36,22 +36,22 @@ namespace JSC { public: DebuggerActivation(JSObject*); - virtual void mark(); + virtual void markChildren(MarkStack&); virtual UString className() const; virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes); virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes); virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp index cd8702b..9c8ca2a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp @@ -41,7 +41,7 @@ const UString* DebuggerCallFrame::functionName() const if (!m_callFrame->codeBlock()) return 0; - JSFunction* function = static_cast<JSFunction*>(m_callFrame->callee()); + JSFunction* function = asFunction(m_callFrame->callee()); if (!function) return 0; return &function->name(&m_callFrame->globalData()); @@ -52,7 +52,7 @@ UString DebuggerCallFrame::calculatedFunctionName() const if (!m_callFrame->codeBlock()) return 0; - JSFunction* function = static_cast<JSFunction*>(m_callFrame->callee()); + JSFunction* function = asFunction(m_callFrame->callee()); if (!function) return 0; return function->calculatedDisplayName(&m_callFrame->globalData()); @@ -79,14 +79,12 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c if (!m_callFrame->codeBlock()) return JSValue(); - int errLine; - UString errMsg; - SourceCode source = makeSource(script); - RefPtr<EvalNode> evalNode = m_callFrame->scopeChain()->globalData->parser->parse<EvalNode>(m_callFrame, m_callFrame->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - if (!evalNode) - return Error::create(m_callFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); + EvalExecutable eval(makeSource(script)); + JSObject* error = eval.compile(m_callFrame, m_callFrame->scopeChain()); + if (error) + return error; - return m_callFrame->scopeChain()->globalData->interpreter->execute(evalNode.get(), m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception); + return m_callFrame->scopeChain()->globalData->interpreter->execute(&eval, m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp index 06c6e38..44559a8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp @@ -1,23 +1,24 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + + 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 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>. */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -28,7 +29,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. */ @@ -46,7 +47,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1" +#define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -54,28 +55,159 @@ /* 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 +#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 -/* Copy the first part of user declarations. */ -/* Line 189 of yacc.c */ + + +/* Copy the first part of user declarations. */ #line 3 "../parser/Grammar.y" @@ -102,18 +234,12 @@ #include "config.h" -#include <string.h> -#include <stdlib.h> -#include "JSValue.h" #include "JSObject.h" -#include "NodeConstructors.h" -#include "Lexer.h" #include "JSString.h" -#include "JSGlobalData.h" -#include "CommonIdentifiers.h" +#include "NodeConstructors.h" #include "NodeInfo.h" -#include "Parser.h" -#include <wtf/FastMalloc.h> +#include <stdlib.h> +#include <string.h> #include <wtf/MathExtras.h> #define YYMALLOC fastMalloc @@ -122,46 +248,44 @@ #define YYMAXDEPTH 10000 #define YYENABLE_NLS 0 -/* default values for bison */ +// Default values for bison. #define YYDEBUG 0 // Set to 1 to debug a parse error. #define jscyydebug 0 // Set to 1 to debug a parse error. #if !PLATFORM(DARWIN) - // avoid triggering warnings in older bison +// Avoid triggering warnings in older bison by not setting this on the Darwin platform. +// FIXME: Is this still needed? #define YYERROR_VERBOSE #endif int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); + static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); #define GLOBAL_DATA static_cast<JSGlobalData*>(globalPtr) -#define LEXER (GLOBAL_DATA->lexer) - -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0) -#define SET_EXCEPTION_LOCATION(node, start, divot, end) node->setExceptionSourceCode((divot), (divot) - (start), (end) - (divot)) -#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line, (s).first_column + 1) +#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*GLOBAL_DATA->lexer, yychar)) YYABORT; } while (0) using namespace JSC; using namespace std; -static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end); -static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static PropertyNode* makeGetterOrSetterPropertyNode(void*, const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); -static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end); -static ExpressionNode* makeTypeOfNode(void*, ExpressionNode*); -static ExpressionNode* makeDeleteNode(void*, ExpressionNode*, int start, int divot, int end); -static ExpressionNode* makeNegateNode(void*, ExpressionNode*); -static NumberNode* makeNumberNode(void*, double); -static ExpressionNode* makeBitwiseNotNode(void*, ExpressionNode*); -static ExpressionNode* makeMultNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeDivNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeAddNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static StatementNode* makeVarStatementNode(void*, ExpressionNode*); -static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, ExpressionNode* init); +static ExpressionNode* makeAssignNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end); +static ExpressionNode* makePrefixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static ExpressionNode* makePostfixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData*, const Identifier& getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData*, ExpressionNodeInfo function, ArgumentsNodeInfo, int start, int divot, int end); +static ExpressionNode* makeTypeOfNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeDeleteNode(JSGlobalData*, ExpressionNode*, int start, int divot, int end); +static ExpressionNode* makeNegateNode(JSGlobalData*, ExpressionNode*); +static NumberNode* makeNumberNode(JSGlobalData*, double); +static ExpressionNode* makeBitwiseNotNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeMultNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeDivNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeAddNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeSubNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeLeftShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeRightShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static StatementNode* makeVarStatementNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* combineCommaNodes(JSGlobalData*, ExpressionNode* list, ExpressionNode* init); #if COMPILER(MSVC) @@ -174,17 +298,17 @@ static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, Expression #define YYPARSE_PARAM globalPtr #define YYLEX_PARAM globalPtr -template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserArenaData<DeclarationStacks::VarStack>* varDecls, - ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, - CodeFeatures info, - int numConstants) +template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, + ParserArenaData<DeclarationStacks::VarStack>* varDecls, + ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, + CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeDeclarationInfo<T> result = { node, varDecls, funcDecls, info, numConstants }; return result; } -template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) +template <typename T> inline NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeInfo<T> result = { node, info, numConstants }; @@ -210,28 +334,24 @@ template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) return decls1; } -static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) { if (!varDecls) - varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - - varDecls->data.append(make_pair(ident, attrs)); + varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>; + varDecls->data.append(make_pair(&ident, attrs)); } -static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) { unsigned attrs = DeclarationStacks::IsConstant; if (decl->hasInitializer()) attrs |= DeclarationStacks::HasInitializer; - appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs); + appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs); } -/* Line 189 of yacc.c */ -#line 234 "JavaScriptCore/tmp/../generated/Grammar.tab.c" - /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -250,91 +370,13 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<D # 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 155 "../parser/Grammar.y" - int intValue; double doubleValue; - Identifier* ident; + const Identifier* ident; // expression subtrees ExpressionNodeInfo expressionNode; @@ -361,15 +403,13 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; - - - -/* Line 214 of yacc.c */ -#line 369 "JavaScriptCore/tmp/../generated/Grammar.tab.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 187 of yacc.c. */ +#line 409 "JavaScriptCore/tmp/../generated/Grammar.tab.c" + YYSTYPE; # 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 @@ -387,10 +427,23 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ +#line 178 "../parser/Grammar.y" + +template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end) +{ + statement->setLoc(start.first_line, end.last_line, start.first_column + 1); +} + +static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end) +{ + node->setExceptionSourceCode(divot, divot - start, end - divot); +} -/* Line 264 of yacc.c */ -#line 394 "JavaScriptCore/tmp/../generated/Grammar.tab.c" + + +/* Line 216 of yacc.c. */ +#line 447 "JavaScriptCore/tmp/../generated/Grammar.tab.c" #ifdef short # undef short @@ -465,14 +518,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int yyi) +YYID (int i) #else static int -YYID (yyi) - int yyi; +YYID (i) + int i; #endif { - return yyi; + return i; } #endif @@ -554,9 +607,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; + yytype_int16 yyss; + YYSTYPE yyvs; + YYLTYPE yyls; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -591,12 +644,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_alloc, Stack) \ +# define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -944,66 +997,66 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 288, 288, 289, 290, 291, 292, 293, 302, 314, - 315, 316, 317, 318, 330, 334, 341, 342, 343, 345, - 349, 350, 351, 352, 353, 357, 358, 359, 363, 367, - 375, 376, 380, 381, 385, 386, 387, 391, 395, 402, - 403, 407, 411, 418, 419, 426, 427, 434, 435, 436, - 440, 446, 447, 448, 452, 459, 460, 464, 468, 475, - 476, 480, 481, 485, 486, 487, 491, 492, 493, 497, - 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, - 510, 511, 515, 516, 520, 521, 522, 523, 527, 528, - 530, 532, 537, 538, 539, 543, 544, 546, 551, 552, - 553, 554, 558, 559, 560, 561, 565, 566, 567, 568, - 569, 570, 573, 579, 580, 581, 582, 583, 584, 591, - 592, 593, 594, 595, 596, 600, 607, 608, 609, 610, - 611, 615, 616, 618, 620, 622, 627, 628, 630, 631, - 633, 638, 639, 643, 644, 649, 650, 654, 655, 659, - 660, 665, 666, 671, 672, 676, 677, 682, 683, 688, - 689, 693, 694, 699, 700, 705, 706, 710, 711, 716, - 717, 721, 722, 727, 728, 733, 734, 739, 740, 747, - 748, 755, 756, 763, 764, 765, 766, 767, 768, 769, - 770, 771, 772, 773, 774, 778, 779, 783, 784, 788, - 789, 793, 794, 795, 796, 797, 798, 799, 800, 801, - 802, 803, 804, 805, 806, 807, 808, 809, 813, 815, - 820, 822, 828, 835, 844, 852, 865, 872, 881, 889, - 902, 904, 910, 918, 930, 931, 935, 939, 943, 947, - 949, 954, 957, 967, 969, 971, 973, 979, 986, 995, - 1001, 1012, 1013, 1017, 1018, 1022, 1026, 1030, 1034, 1041, - 1044, 1047, 1050, 1056, 1059, 1062, 1065, 1071, 1077, 1083, - 1084, 1093, 1094, 1098, 1104, 1114, 1115, 1119, 1120, 1124, - 1130, 1134, 1141, 1147, 1153, 1163, 1165, 1170, 1171, 1182, - 1183, 1190, 1191, 1201, 1204, 1210, 1211, 1215, 1216, 1221, - 1228, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1249, 1250, - 1251, 1252, 1253, 1257, 1258, 1262, 1263, 1264, 1266, 1270, - 1271, 1272, 1273, 1274, 1278, 1279, 1280, 1284, 1285, 1288, - 1290, 1294, 1295, 1299, 1300, 1301, 1302, 1303, 1307, 1308, - 1309, 1310, 1314, 1315, 1319, 1320, 1324, 1325, 1326, 1327, - 1331, 1332, 1333, 1334, 1338, 1339, 1343, 1344, 1348, 1349, - 1353, 1354, 1358, 1359, 1360, 1364, 1365, 1366, 1370, 1371, - 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1383, - 1384, 1388, 1389, 1393, 1394, 1395, 1396, 1400, 1401, 1402, - 1403, 1407, 1408, 1409, 1413, 1414, 1415, 1419, 1420, 1421, - 1422, 1426, 1427, 1428, 1429, 1433, 1434, 1435, 1436, 1437, - 1438, 1439, 1443, 1444, 1445, 1446, 1447, 1448, 1452, 1453, - 1454, 1455, 1456, 1457, 1458, 1462, 1463, 1464, 1465, 1466, - 1470, 1471, 1472, 1473, 1474, 1478, 1479, 1480, 1481, 1482, - 1486, 1487, 1491, 1492, 1496, 1497, 1501, 1502, 1506, 1507, - 1511, 1512, 1516, 1517, 1521, 1522, 1526, 1527, 1531, 1532, - 1536, 1537, 1541, 1542, 1546, 1547, 1551, 1552, 1556, 1557, - 1561, 1562, 1566, 1567, 1571, 1572, 1576, 1577, 1581, 1582, - 1586, 1587, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, - 1599, 1600, 1601, 1602, 1606, 1607, 1611, 1612, 1616, 1617, - 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, - 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1641, 1642, 1646, - 1647, 1651, 1652, 1653, 1654, 1658, 1659, 1660, 1661, 1665, - 1666, 1670, 1671, 1675, 1676, 1680, 1684, 1688, 1692, 1693, - 1697, 1698, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, - 1712, 1714, 1717, 1719, 1723, 1724, 1725, 1726, 1730, 1731, - 1732, 1733, 1737, 1738, 1739, 1740, 1744, 1748, 1752, 1753, - 1756, 1758, 1762, 1763, 1767, 1768, 1772, 1773, 1777, 1781, - 1782, 1786, 1787, 1788, 1792, 1793, 1797, 1798, 1802, 1803, - 1804, 1805, 1809, 1810, 1813, 1815, 1819, 1820 + 0, 293, 293, 294, 295, 296, 297, 298, 309, 323, + 324, 325, 326, 327, 339, 343, 350, 351, 352, 354, + 358, 359, 360, 361, 362, 366, 367, 368, 372, 376, + 384, 385, 389, 390, 394, 395, 396, 400, 404, 411, + 412, 416, 420, 427, 428, 435, 436, 443, 444, 445, + 449, 455, 456, 457, 461, 468, 469, 473, 477, 484, + 485, 489, 490, 494, 495, 496, 500, 501, 502, 506, + 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, + 519, 520, 524, 525, 529, 530, 531, 532, 536, 537, + 539, 541, 546, 547, 548, 552, 553, 555, 560, 561, + 562, 563, 567, 568, 569, 570, 574, 575, 576, 577, + 578, 579, 582, 588, 589, 590, 591, 592, 593, 600, + 601, 602, 603, 604, 605, 609, 616, 617, 618, 619, + 620, 624, 625, 627, 629, 631, 636, 637, 639, 640, + 642, 647, 648, 652, 653, 658, 659, 663, 664, 668, + 669, 674, 675, 680, 681, 685, 686, 691, 692, 697, + 698, 702, 703, 708, 709, 714, 715, 719, 720, 725, + 726, 730, 731, 736, 737, 742, 743, 748, 749, 756, + 757, 764, 765, 772, 773, 774, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 787, 788, 792, 793, 797, + 798, 802, 803, 804, 805, 806, 807, 808, 809, 810, + 811, 812, 813, 814, 815, 816, 817, 818, 822, 824, + 829, 831, 837, 844, 853, 861, 874, 881, 890, 898, + 911, 913, 919, 927, 939, 940, 944, 948, 952, 956, + 958, 963, 966, 976, 978, 980, 982, 988, 995, 1004, + 1010, 1021, 1022, 1026, 1027, 1031, 1035, 1039, 1043, 1050, + 1053, 1056, 1059, 1065, 1068, 1071, 1074, 1080, 1086, 1092, + 1093, 1102, 1103, 1107, 1113, 1123, 1124, 1128, 1129, 1133, + 1139, 1143, 1150, 1156, 1162, 1172, 1174, 1179, 1180, 1191, + 1192, 1199, 1200, 1210, 1213, 1219, 1220, 1224, 1225, 1230, + 1237, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1258, 1259, + 1260, 1261, 1262, 1266, 1267, 1271, 1272, 1273, 1275, 1279, + 1280, 1281, 1282, 1283, 1287, 1288, 1289, 1293, 1294, 1297, + 1299, 1303, 1304, 1308, 1309, 1310, 1311, 1312, 1316, 1317, + 1318, 1319, 1323, 1324, 1328, 1329, 1333, 1334, 1335, 1336, + 1340, 1341, 1342, 1343, 1347, 1348, 1352, 1353, 1357, 1358, + 1362, 1363, 1367, 1368, 1369, 1373, 1374, 1375, 1379, 1380, + 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1392, + 1393, 1397, 1398, 1402, 1403, 1404, 1405, 1409, 1410, 1411, + 1412, 1416, 1417, 1418, 1422, 1423, 1424, 1428, 1429, 1430, + 1431, 1435, 1436, 1437, 1438, 1442, 1443, 1444, 1445, 1446, + 1447, 1448, 1452, 1453, 1454, 1455, 1456, 1457, 1461, 1462, + 1463, 1464, 1465, 1466, 1467, 1471, 1472, 1473, 1474, 1475, + 1479, 1480, 1481, 1482, 1483, 1487, 1488, 1489, 1490, 1491, + 1495, 1496, 1500, 1501, 1505, 1506, 1510, 1511, 1515, 1516, + 1520, 1521, 1525, 1526, 1530, 1531, 1535, 1536, 1540, 1541, + 1545, 1546, 1550, 1551, 1555, 1556, 1560, 1561, 1565, 1566, + 1570, 1571, 1575, 1576, 1580, 1581, 1585, 1586, 1590, 1591, + 1595, 1596, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, + 1608, 1609, 1610, 1611, 1615, 1616, 1620, 1621, 1625, 1626, + 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, + 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1650, 1651, 1655, + 1656, 1660, 1661, 1662, 1663, 1667, 1668, 1669, 1670, 1674, + 1675, 1679, 1680, 1684, 1685, 1689, 1693, 1697, 1701, 1702, + 1706, 1707, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, + 1721, 1723, 1726, 1728, 1732, 1733, 1734, 1735, 1739, 1740, + 1741, 1742, 1746, 1747, 1748, 1749, 1753, 1757, 1761, 1762, + 1765, 1767, 1771, 1772, 1776, 1777, 1781, 1782, 1786, 1790, + 1791, 1795, 1796, 1797, 1801, 1802, 1806, 1807, 1811, 1812, + 1813, 1814, 1818, 1819, 1822, 1824, 1828, 1829 }; #endif @@ -2310,20 +2363,17 @@ 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 *yybottom, yytype_int16 *yytop) +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } @@ -2358,11 +2408,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - YYFPRINTF (stderr, " $%d = ", yyi + 1); + fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); + fprintf (stderr, "\n"); } } @@ -2644,8 +2694,10 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) break; } } + /* Prevent warnings from -Wmissing-prototypes. */ + #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -2664,9 +2716,10 @@ int yyparse (); -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ + +/*----------. +| yyparse. | +`----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -2690,97 +2743,88 @@ yyparse () #endif #endif { -/* The lookahead symbol. */ + /* The look-ahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; -/* Location data for the lookahead symbol. */ +/* Number of syntax errors so far. */ +int yynerrs; +/* Location data for the look-ahead symbol. */ YYLTYPE yylloc; - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + 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 - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - YYSIZE_T yystacksize; + YYSIZE_T yystacksize = YYINITDEPTH; - 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 = 1; + yylloc.first_column = yylloc.last_column = 0; #endif goto yysetstate; @@ -2819,7 +2863,6 @@ YYLTYPE yylloc; &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); - yyls = yyls1; yyss = yyss1; yyvs = yyvs1; @@ -2841,9 +2884,9 @@ YYLTYPE yylloc; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + YYSTACK_RELOCATE (yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2864,9 +2907,6 @@ YYLTYPE yylloc; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - if (yystate == YYFINAL) - YYACCEPT; - goto yybackup; /*-----------. @@ -2875,16 +2915,16 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ + look-ahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2916,16 +2956,20 @@ yybackup: goto yyreduce; } + if (yyn == YYFINAL) + YYACCEPT; + /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the lookahead token. */ + /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token. */ - yychar = YYEMPTY; + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -2966,116 +3010,94 @@ yyreduce: switch (yyn) { case 2: - -/* Line 1455 of yacc.c */ -#line 288 "../parser/Grammar.y" +#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 289 "../parser/Grammar.y" +#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 290 "../parser/Grammar.y" +#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 291 "../parser/Grammar.y" +#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 292 "../parser/Grammar.y" +#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 293 "../parser/Grammar.y" +#line 298 "../parser/Grammar.y" { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags)) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (1)]).first_column, (yylsp[(1) - (1)]).first_column + size, (yylsp[(1) - (1)]).first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, (yylsp[(1) - (1)]).first_column, (yylsp[(1) - (1)]).first_column + size, (yylsp[(1) - (1)]).first_column + size); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, 0, 0); ;} break; case 8: - -/* Line 1455 of yacc.c */ -#line 302 "../parser/Grammar.y" +#line 309 "../parser/Grammar.y" { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags, '=')) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (1)]).first_column, (yylsp[(1) - (1)]).first_column + size, (yylsp[(1) - (1)]).first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, (yylsp[(1) - (1)]).first_column, (yylsp[(1) - (1)]).first_column + size, (yylsp[(1) - (1)]).first_column + size); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, 0, 0); ;} break; case 9: - -/* Line 1455 of yacc.c */ -#line 314 "../parser/Grammar.y" +#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 315 "../parser/Grammar.y" +#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 316 "../parser/Grammar.y" - { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from((yyvsp[(1) - (3)].doubleValue))), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} +#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 317 "../parser/Grammar.y" - { (yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), 0, (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); if (!(yyval.propertyNode).m_node) YYABORT; ;} +#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 319 "../parser/Grammar.y" +#line 328 "../parser/Grammar.y" { - (yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (8)].ident), *(yyvsp[(2) - (8)].ident), (yyvsp[(4) - (8)].parameterList).m_node.head, (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line)), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); + (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); if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature) (yyvsp[(7) - (8)].functionBodyNode)->setUsesArguments(); - DBG((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); + setStatementLocation((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); if (!(yyval.propertyNode).m_node) YYABORT; ;} break; case 14: - -/* Line 1455 of yacc.c */ -#line 330 "../parser/Grammar.y" +#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; (yyval.propertyList).m_features = (yyvsp[(1) - (1)].propertyNode).m_features; @@ -3083,9 +3105,7 @@ yyreduce: break; case 15: - -/* Line 1455 of yacc.c */ -#line 334 "../parser/Grammar.y" +#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); (yyval.propertyList).m_features = (yyvsp[(1) - (3)].propertyList).m_features | (yyvsp[(3) - (3)].propertyNode).m_features; @@ -3093,72 +3113,52 @@ yyreduce: break; case 17: - -/* Line 1455 of yacc.c */ -#line 342 "../parser/Grammar.y" +#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 343 "../parser/Grammar.y" +#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 345 "../parser/Grammar.y" +#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 349 "../parser/Grammar.y" +#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 352 "../parser/Grammar.y" +#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 353 "../parser/Grammar.y" +#line 362 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (3)].expressionNode); ;} break; case 25: - -/* Line 1455 of yacc.c */ -#line 357 "../parser/Grammar.y" +#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 358 "../parser/Grammar.y" +#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 359 "../parser/Grammar.y" +#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 363 "../parser/Grammar.y" +#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; (yyval.elementList).m_features = (yyvsp[(2) - (2)].expressionNode).m_features; @@ -3166,9 +3166,7 @@ yyreduce: break; case 29: - -/* Line 1455 of yacc.c */ -#line 368 "../parser/Grammar.y" +#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); (yyval.elementList).m_features = (yyvsp[(1) - (4)].elementList).m_features | (yyvsp[(4) - (4)].expressionNode).m_features; @@ -3176,198 +3174,152 @@ yyreduce: break; case 30: - -/* Line 1455 of yacc.c */ -#line 375 "../parser/Grammar.y" +#line 384 "../parser/Grammar.y" { (yyval.intValue) = 0; ;} break; case 32: - -/* Line 1455 of yacc.c */ -#line 380 "../parser/Grammar.y" +#line 389 "../parser/Grammar.y" { (yyval.intValue) = 1; ;} break; case 33: - -/* Line 1455 of yacc.c */ -#line 381 "../parser/Grammar.y" +#line 390 "../parser/Grammar.y" { (yyval.intValue) = (yyvsp[(1) - (2)].intValue) + 1; ;} break; case 35: - -/* Line 1455 of yacc.c */ -#line 386 "../parser/Grammar.y" +#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 387 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants); ;} break; case 37: - -/* Line 1455 of yacc.c */ -#line 391 "../parser/Grammar.y" +#line 400 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants); ;} break; case 38: - -/* Line 1455 of yacc.c */ -#line 395 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].argumentsNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].argumentsNode).m_numConstants); ;} break; case 40: - -/* Line 1455 of yacc.c */ -#line 403 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants); ;} break; case 41: - -/* Line 1455 of yacc.c */ -#line 407 "../parser/Grammar.y" +#line 416 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants); ;} break; case 42: - -/* Line 1455 of yacc.c */ -#line 411 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].argumentsNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].argumentsNode).m_numConstants); ;} break; case 44: - -/* Line 1455 of yacc.c */ -#line 419 "../parser/Grammar.y" +#line 428 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 46: - -/* Line 1455 of yacc.c */ -#line 427 "../parser/Grammar.y" +#line 436 "../parser/Grammar.y" { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 47: - -/* Line 1455 of yacc.c */ -#line 434 "../parser/Grammar.y" - { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} +#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 435 "../parser/Grammar.y" - { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} +#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 436 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants); ;} break; case 50: - -/* Line 1455 of yacc.c */ -#line 440 "../parser/Grammar.y" +#line 449 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants); ;} break; case 51: - -/* Line 1455 of yacc.c */ -#line 446 "../parser/Grammar.y" - { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} +#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 447 "../parser/Grammar.y" - { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} +#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 448 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants); ;} break; case 54: - -/* Line 1455 of yacc.c */ -#line 452 "../parser/Grammar.y" +#line 461 "../parser/Grammar.y" { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants); ;} break; case 55: - -/* Line 1455 of yacc.c */ -#line 459 "../parser/Grammar.y" +#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 460 "../parser/Grammar.y" +#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 464 "../parser/Grammar.y" +#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; (yyval.argumentList).m_features = (yyvsp[(1) - (1)].expressionNode).m_features; @@ -3375,9 +3327,7 @@ yyreduce: break; case 58: - -/* Line 1455 of yacc.c */ -#line 468 "../parser/Grammar.y" +#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); (yyval.argumentList).m_features = (yyvsp[(1) - (3)].argumentList).m_features | (yyvsp[(3) - (3)].expressionNode).m_features; @@ -3385,730 +3335,528 @@ yyreduce: break; case 64: - -/* Line 1455 of yacc.c */ -#line 486 "../parser/Grammar.y" +#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 487 "../parser/Grammar.y" +#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 492 "../parser/Grammar.y" +#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 493 "../parser/Grammar.y" +#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 497 "../parser/Grammar.y" +#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 498 "../parser/Grammar.y" +#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 499 "../parser/Grammar.y" +#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 500 "../parser/Grammar.y" +#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 501 "../parser/Grammar.y" +#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 502 "../parser/Grammar.y" +#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 503 "../parser/Grammar.y" +#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 504 "../parser/Grammar.y" +#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 505 "../parser/Grammar.y" +#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 506 "../parser/Grammar.y" +#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 507 "../parser/Grammar.y" +#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 521 "../parser/Grammar.y" +#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 522 "../parser/Grammar.y" +#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 523 "../parser/Grammar.y" +#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 529 "../parser/Grammar.y" +#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 531 "../parser/Grammar.y" +#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 533 "../parser/Grammar.y" +#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 538 "../parser/Grammar.y" +#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 539 "../parser/Grammar.y" +#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 545 "../parser/Grammar.y" +#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 547 "../parser/Grammar.y" +#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 552 "../parser/Grammar.y" +#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 553 "../parser/Grammar.y" +#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 554 "../parser/Grammar.y" +#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 559 "../parser/Grammar.y" +#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 560 "../parser/Grammar.y" +#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 561 "../parser/Grammar.y" +#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 566 "../parser/Grammar.y" +#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 567 "../parser/Grammar.y" +#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 568 "../parser/Grammar.y" +#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 569 "../parser/Grammar.y" +#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 570 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(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 112: - -/* Line 1455 of yacc.c */ -#line 573 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(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 114: - -/* Line 1455 of yacc.c */ -#line 580 "../parser/Grammar.y" +#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 581 "../parser/Grammar.y" +#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 582 "../parser/Grammar.y" +#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 583 "../parser/Grammar.y" +#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 585 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(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 120: - -/* Line 1455 of yacc.c */ -#line 592 "../parser/Grammar.y" +#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 593 "../parser/Grammar.y" +#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 594 "../parser/Grammar.y" +#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 595 "../parser/Grammar.y" +#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 597 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(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 125: - -/* Line 1455 of yacc.c */ -#line 601 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(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 127: - -/* Line 1455 of yacc.c */ -#line 608 "../parser/Grammar.y" +#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 609 "../parser/Grammar.y" +#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 610 "../parser/Grammar.y" +#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 611 "../parser/Grammar.y" +#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 617 "../parser/Grammar.y" +#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 619 "../parser/Grammar.y" +#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 621 "../parser/Grammar.y" +#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 623 "../parser/Grammar.y" +#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 629 "../parser/Grammar.y" +#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 630 "../parser/Grammar.y" +#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 632 "../parser/Grammar.y" +#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 634 "../parser/Grammar.y" +#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 639 "../parser/Grammar.y" +#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 645 "../parser/Grammar.y" +#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 650 "../parser/Grammar.y" +#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 655 "../parser/Grammar.y" +#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 661 "../parser/Grammar.y" +#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 667 "../parser/Grammar.y" +#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 672 "../parser/Grammar.y" +#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 678 "../parser/Grammar.y" +#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 684 "../parser/Grammar.y" +#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 689 "../parser/Grammar.y" +#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 695 "../parser/Grammar.y" +#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 701 "../parser/Grammar.y" +#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 706 "../parser/Grammar.y" +#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 712 "../parser/Grammar.y" +#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 717 "../parser/Grammar.y" +#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 723 "../parser/Grammar.y" +#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 729 "../parser/Grammar.y" +#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 735 "../parser/Grammar.y" +#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 741 "../parser/Grammar.y" +#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); ;} break; case 180: - -/* Line 1455 of yacc.c */ -#line 749 "../parser/Grammar.y" +#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); ;} break; case 182: - -/* Line 1455 of yacc.c */ -#line 757 "../parser/Grammar.y" +#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); ;} break; case 183: - -/* Line 1455 of yacc.c */ -#line 763 "../parser/Grammar.y" +#line 772 "../parser/Grammar.y" { (yyval.op) = OpEqual; ;} break; case 184: - -/* Line 1455 of yacc.c */ -#line 764 "../parser/Grammar.y" +#line 773 "../parser/Grammar.y" { (yyval.op) = OpPlusEq; ;} break; case 185: - -/* Line 1455 of yacc.c */ -#line 765 "../parser/Grammar.y" +#line 774 "../parser/Grammar.y" { (yyval.op) = OpMinusEq; ;} break; case 186: - -/* Line 1455 of yacc.c */ -#line 766 "../parser/Grammar.y" +#line 775 "../parser/Grammar.y" { (yyval.op) = OpMultEq; ;} break; case 187: - -/* Line 1455 of yacc.c */ -#line 767 "../parser/Grammar.y" +#line 776 "../parser/Grammar.y" { (yyval.op) = OpDivEq; ;} break; case 188: - -/* Line 1455 of yacc.c */ -#line 768 "../parser/Grammar.y" +#line 777 "../parser/Grammar.y" { (yyval.op) = OpLShift; ;} break; case 189: - -/* Line 1455 of yacc.c */ -#line 769 "../parser/Grammar.y" +#line 778 "../parser/Grammar.y" { (yyval.op) = OpRShift; ;} break; case 190: - -/* Line 1455 of yacc.c */ -#line 770 "../parser/Grammar.y" +#line 779 "../parser/Grammar.y" { (yyval.op) = OpURShift; ;} break; case 191: - -/* Line 1455 of yacc.c */ -#line 771 "../parser/Grammar.y" +#line 780 "../parser/Grammar.y" { (yyval.op) = OpAndEq; ;} break; case 192: - -/* Line 1455 of yacc.c */ -#line 772 "../parser/Grammar.y" +#line 781 "../parser/Grammar.y" { (yyval.op) = OpXOrEq; ;} break; case 193: - -/* Line 1455 of yacc.c */ -#line 773 "../parser/Grammar.y" +#line 782 "../parser/Grammar.y" { (yyval.op) = OpOrEq; ;} break; case 194: - -/* Line 1455 of yacc.c */ -#line 774 "../parser/Grammar.y" +#line 783 "../parser/Grammar.y" { (yyval.op) = OpModEq; ;} break; case 196: - -/* Line 1455 of yacc.c */ -#line 779 "../parser/Grammar.y" +#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 784 "../parser/Grammar.y" +#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 789 "../parser/Grammar.y" +#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 813 "../parser/Grammar.y" +#line 822 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 219: - -/* Line 1455 of yacc.c */ -#line 815 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 220: - -/* Line 1455 of yacc.c */ -#line 820 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 221: - -/* Line 1455 of yacc.c */ -#line 822 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 222: - -/* Line 1455 of yacc.c */ -#line 828 "../parser/Grammar.y" +#line 837 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (1)].ident), 0); @@ -4119,11 +3867,9 @@ yyreduce: break; case 223: - -/* Line 1455 of yacc.c */ -#line 835 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); (yyval.varDeclList).m_node = node; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (2)].ident), DeclarationStacks::HasInitializer); @@ -4134,9 +3880,7 @@ yyreduce: break; case 224: - -/* Line 1455 of yacc.c */ -#line 845 "../parser/Grammar.y" +#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; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (3)].ident), 0); @@ -4147,11 +3891,9 @@ yyreduce: break; case 225: - -/* Line 1455 of yacc.c */ -#line 853 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); (yyval.varDeclList).m_node = combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (4)].varDeclList).m_node, node); (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (4)].varDeclList).m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (4)].ident), DeclarationStacks::HasInitializer); @@ -4162,9 +3904,7 @@ yyreduce: break; case 226: - -/* Line 1455 of yacc.c */ -#line 865 "../parser/Grammar.y" +#line 874 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (1)].ident), 0); @@ -4175,11 +3915,9 @@ yyreduce: break; case 227: - -/* Line 1455 of yacc.c */ -#line 872 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); (yyval.varDeclList).m_node = node; (yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (2)].ident), DeclarationStacks::HasInitializer); @@ -4190,9 +3928,7 @@ yyreduce: break; case 228: - -/* Line 1455 of yacc.c */ -#line 882 "../parser/Grammar.y" +#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; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (3)].ident), 0); @@ -4203,11 +3939,9 @@ yyreduce: break; case 229: - -/* Line 1455 of yacc.c */ -#line 890 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); + setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); (yyval.varDeclList).m_node = combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (4)].varDeclList).m_node, node); (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (4)].varDeclList).m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (4)].ident), DeclarationStacks::HasInitializer); @@ -4218,25 +3952,19 @@ yyreduce: break; case 230: - -/* Line 1455 of yacc.c */ -#line 902 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 231: - -/* Line 1455 of yacc.c */ -#line 905 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 232: - -/* Line 1455 of yacc.c */ -#line 910 "../parser/Grammar.y" +#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; (yyval.constDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; @@ -4248,9 +3976,7 @@ yyreduce: break; case 233: - -/* Line 1455 of yacc.c */ -#line 919 "../parser/Grammar.y" +#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; (yyval.constDeclList).m_node.tail = (yyvsp[(3) - (3)].constDeclNode).m_node; @@ -4262,316 +3988,246 @@ yyreduce: break; case 234: - -/* Line 1455 of yacc.c */ -#line 930 "../parser/Grammar.y" +#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 931 "../parser/Grammar.y" +#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 935 "../parser/Grammar.y" +#line 944 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 237: - -/* Line 1455 of yacc.c */ -#line 939 "../parser/Grammar.y" +#line 948 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 238: - -/* Line 1455 of yacc.c */ -#line 943 "../parser/Grammar.y" +#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 947 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 240: - -/* Line 1455 of yacc.c */ -#line 949 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 241: - -/* Line 1455 of yacc.c */ -#line 955 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 242: - -/* Line 1455 of yacc.c */ -#line 958 "../parser/Grammar.y" +#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), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations), (yyvsp[(3) - (7)].expressionNode).m_features | (yyvsp[(5) - (7)].statementNode).m_features | (yyvsp[(7) - (7)].statementNode).m_features, (yyvsp[(3) - (7)].expressionNode).m_numConstants + (yyvsp[(5) - (7)].statementNode).m_numConstants + (yyvsp[(7) - (7)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(4) - (7)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(4) - (7)])); ;} break; case 243: - -/* Line 1455 of yacc.c */ -#line 967 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 244: - -/* Line 1455 of yacc.c */ -#line 969 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 245: - -/* Line 1455 of yacc.c */ -#line 971 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 246: - -/* Line 1455 of yacc.c */ -#line 974 "../parser/Grammar.y" +#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, (yyvsp[(3) - (9)].expressionNode).m_numConstants + (yyvsp[(5) - (9)].expressionNode).m_numConstants + (yyvsp[(7) - (9)].expressionNode).m_numConstants + (yyvsp[(9) - (9)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); ;} break; case 247: - -/* Line 1455 of yacc.c */ -#line 980 "../parser/Grammar.y" +#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), mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_funcDeclarations, (yyvsp[(10) - (10)].statementNode).m_funcDeclarations), (yyvsp[(4) - (10)].varDeclList).m_features | (yyvsp[(6) - (10)].expressionNode).m_features | (yyvsp[(8) - (10)].expressionNode).m_features | (yyvsp[(10) - (10)].statementNode).m_features, (yyvsp[(4) - (10)].varDeclList).m_numConstants + (yyvsp[(6) - (10)].expressionNode).m_numConstants + (yyvsp[(8) - (10)].expressionNode).m_numConstants + (yyvsp[(10) - (10)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (10)]), (yylsp[(9) - (10)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (10)]), (yylsp[(9) - (10)])); ;} break; case 248: - -/* Line 1455 of yacc.c */ -#line 987 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (7)]).first_column, (yylsp[(3) - (7)]).last_column, (yylsp[(5) - (7)]).last_column); + setExceptionLocation(node, (yylsp[(3) - (7)]).first_column, (yylsp[(3) - (7)]).last_column, (yylsp[(5) - (7)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, (yyvsp[(7) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations, (yyvsp[(3) - (7)].expressionNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features | (yyvsp[(7) - (7)].statementNode).m_features, (yyvsp[(3) - (7)].expressionNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants + (yyvsp[(7) - (7)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(6) - (7)])); + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(6) - (7)])); ;} break; case 249: - -/* Line 1455 of yacc.c */ -#line 996 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column); + setExceptionLocation(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column); appendToVarDeclarationList(GLOBAL_DATA, (yyvsp[(8) - (8)].statementNode).m_varDeclarations, *(yyvsp[(4) - (8)].ident), DeclarationStacks::HasInitializer); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(forIn, (yyvsp[(8) - (8)].statementNode).m_varDeclarations, (yyvsp[(8) - (8)].statementNode).m_funcDeclarations, ((*(yyvsp[(4) - (8)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(6) - (8)].expressionNode).m_features | (yyvsp[(8) - (8)].statementNode).m_features, (yyvsp[(6) - (8)].expressionNode).m_numConstants + (yyvsp[(8) - (8)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (8)]), (yylsp[(7) - (8)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (8)]), (yylsp[(7) - (8)])); ;} break; case 250: - -/* Line 1455 of yacc.c */ -#line 1002 "../parser/Grammar.y" +#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); - SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column); + setExceptionLocation(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column); appendToVarDeclarationList(GLOBAL_DATA, (yyvsp[(9) - (9)].statementNode).m_varDeclarations, *(yyvsp[(4) - (9)].ident), DeclarationStacks::HasInitializer); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(forIn, (yyvsp[(9) - (9)].statementNode).m_varDeclarations, (yyvsp[(9) - (9)].statementNode).m_funcDeclarations, ((*(yyvsp[(4) - (9)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(5) - (9)].expressionNode).m_features | (yyvsp[(7) - (9)].expressionNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features, (yyvsp[(5) - (9)].expressionNode).m_numConstants + (yyvsp[(7) - (9)].expressionNode).m_numConstants + (yyvsp[(9) - (9)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); ;} break; case 251: - -/* Line 1455 of yacc.c */ -#line 1012 "../parser/Grammar.y" +#line 1021 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;} break; case 253: - -/* Line 1455 of yacc.c */ -#line 1017 "../parser/Grammar.y" +#line 1026 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;} break; case 255: - -/* Line 1455 of yacc.c */ -#line 1022 "../parser/Grammar.y" +#line 1031 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 256: - -/* Line 1455 of yacc.c */ -#line 1026 "../parser/Grammar.y" +#line 1035 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 257: - -/* Line 1455 of yacc.c */ -#line 1030 "../parser/Grammar.y" +#line 1039 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 258: - -/* Line 1455 of yacc.c */ -#line 1034 "../parser/Grammar.y" +#line 1043 "../parser/Grammar.y" { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 259: - -/* Line 1455 of yacc.c */ -#line 1041 "../parser/Grammar.y" +#line 1050 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 260: - -/* Line 1455 of yacc.c */ -#line 1044 "../parser/Grammar.y" +#line 1053 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 261: - -/* Line 1455 of yacc.c */ -#line 1047 "../parser/Grammar.y" +#line 1056 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 262: - -/* Line 1455 of yacc.c */ -#line 1050 "../parser/Grammar.y" +#line 1059 "../parser/Grammar.y" { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 263: - -/* Line 1455 of yacc.c */ -#line 1056 "../parser/Grammar.y" +#line 1065 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 264: - -/* Line 1455 of yacc.c */ -#line 1059 "../parser/Grammar.y" +#line 1068 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} + setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 265: - -/* Line 1455 of yacc.c */ -#line 1062 "../parser/Grammar.y" +#line 1071 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 266: - -/* Line 1455 of yacc.c */ -#line 1065 "../parser/Grammar.y" +#line 1074 "../parser/Grammar.y" { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 267: - -/* Line 1455 of yacc.c */ -#line 1071 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 268: - -/* Line 1455 of yacc.c */ -#line 1077 "../parser/Grammar.y" +#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); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 269: - -/* Line 1455 of yacc.c */ -#line 1083 "../parser/Grammar.y" +#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 1085 "../parser/Grammar.y" +#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), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_funcDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_funcDeclarations), (yyvsp[(4) - (5)].clauseList).m_funcDeclarations), @@ -4580,16 +4236,12 @@ yyreduce: break; case 271: - -/* Line 1455 of yacc.c */ -#line 1093 "../parser/Grammar.y" +#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 1098 "../parser/Grammar.y" +#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; (yyval.clauseList).m_varDeclarations = (yyvsp[(1) - (1)].caseClauseNode).m_varDeclarations; @@ -4599,9 +4251,7 @@ yyreduce: break; case 274: - -/* Line 1455 of yacc.c */ -#line 1104 "../parser/Grammar.y" +#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); (yyval.clauseList).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].clauseList).m_varDeclarations, (yyvsp[(2) - (2)].caseClauseNode).m_varDeclarations); @@ -4612,223 +4262,173 @@ yyreduce: break; case 275: - -/* Line 1455 of yacc.c */ -#line 1114 "../parser/Grammar.y" +#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 1115 "../parser/Grammar.y" +#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 1119 "../parser/Grammar.y" +#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 1120 "../parser/Grammar.y" +#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 1124 "../parser/Grammar.y" +#line 1133 "../parser/Grammar.y" { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].statementNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, (yyvsp[(3) - (3)].statementNode).m_varDeclarations, (yyvsp[(3) - (3)].statementNode).m_funcDeclarations, (yyvsp[(3) - (3)].statementNode).m_features, (yyvsp[(3) - (3)].statementNode).m_numConstants); ;} break; case 280: - -/* Line 1455 of yacc.c */ -#line 1130 "../parser/Grammar.y" +#line 1139 "../parser/Grammar.y" { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); ;} break; case 281: - -/* Line 1455 of yacc.c */ -#line 1134 "../parser/Grammar.y" +#line 1143 "../parser/Grammar.y" { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); - SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; + setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); + (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 282: - -/* Line 1455 of yacc.c */ -#line 1141 "../parser/Grammar.y" +#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), mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_funcDeclarations, (yyvsp[(4) - (4)].statementNode).m_funcDeclarations), (yyvsp[(2) - (4)].statementNode).m_features | (yyvsp[(4) - (4)].statementNode).m_features, (yyvsp[(2) - (4)].statementNode).m_numConstants + (yyvsp[(4) - (4)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (4)]), (yylsp[(2) - (4)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (4)]), (yylsp[(2) - (4)])); ;} break; case 283: - -/* Line 1455 of yacc.c */ -#line 1147 "../parser/Grammar.y" +#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), mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations), (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(7) - (7)].statementNode).m_features | CatchFeature, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(7) - (7)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(2) - (7)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(2) - (7)])); ;} break; case 284: - -/* Line 1455 of yacc.c */ -#line 1154 "../parser/Grammar.y" +#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), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_funcDeclarations, (yyvsp[(7) - (9)].statementNode).m_funcDeclarations), (yyvsp[(9) - (9)].statementNode).m_funcDeclarations), (yyvsp[(2) - (9)].statementNode).m_features | (yyvsp[(7) - (9)].statementNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features | CatchFeature, (yyvsp[(2) - (9)].statementNode).m_numConstants + (yyvsp[(7) - (9)].statementNode).m_numConstants + (yyvsp[(9) - (9)].statementNode).m_numConstants); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(2) - (9)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (9)]), (yylsp[(2) - (9)])); ;} break; case 285: - -/* Line 1455 of yacc.c */ -#line 1163 "../parser/Grammar.y" +#line 1172 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 286: - -/* Line 1455 of yacc.c */ -#line 1165 "../parser/Grammar.y" +#line 1174 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} + setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 287: - -/* Line 1455 of yacc.c */ -#line 1170 "../parser/Grammar.y" - { (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), 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); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); (yyval.statementNode).m_funcDeclarations->data.append(static_cast<FuncDeclNode*>((yyval.statementNode).m_node)); ;} +#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 1172 "../parser/Grammar.y" - { - (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), 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); +#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); if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature) - (yyvsp[(7) - (8)].functionBodyNode)->setUsesArguments(); - DBG((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); - (yyval.statementNode).m_funcDeclarations->data.append(static_cast<FuncDeclNode*>((yyval.statementNode).m_node)); + (yyvsp[(7) - (8)].functionBodyNode)->setUsesArguments(); + setStatementLocation((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); + (yyval.statementNode).m_funcDeclarations->data.append(static_cast<FuncDeclNode*>((yyval.statementNode).m_node)->body()); ;} break; case 289: - -/* Line 1455 of yacc.c */ -#line 1182 "../parser/Grammar.y" - { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(5) - (6)].functionBodyNode), LEXER->sourceCode((yyvsp[(4) - (6)].intValue), (yyvsp[(6) - (6)].intValue), (yylsp[(4) - (6)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(5) - (6)].functionBodyNode), (yylsp[(4) - (6)]), (yylsp[(6) - (6)])); ;} +#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 1184 "../parser/Grammar.y" - { - (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(6) - (7)].functionBodyNode), 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); - if ((yyvsp[(3) - (7)].parameterList).m_features & ArgumentsFeature) +#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); + if ((yyvsp[(3) - (7)].parameterList).m_features & ArgumentsFeature) (yyvsp[(6) - (7)].functionBodyNode)->setUsesArguments(); - DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); + setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;} break; case 291: - -/* Line 1455 of yacc.c */ -#line 1190 "../parser/Grammar.y" - { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;} +#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 1192 "../parser/Grammar.y" - { - (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), 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); +#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); if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature) (yyvsp[(7) - (8)].functionBodyNode)->setUsesArguments(); - DBG((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); + setStatementLocation((yyvsp[(7) - (8)].functionBodyNode), (yylsp[(6) - (8)]), (yylsp[(8) - (8)])); ;} break; case 293: - -/* Line 1455 of yacc.c */ -#line 1201 "../parser/Grammar.y" +#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; (yyval.parameterList).m_node.tail = (yyval.parameterList).m_node.head; ;} break; case 294: - -/* Line 1455 of yacc.c */ -#line 1204 "../parser/Grammar.y" +#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); (yyval.parameterList).m_node.tail = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].parameterList).m_node.tail, *(yyvsp[(3) - (3)].ident)); ;} break; case 295: - -/* Line 1455 of yacc.c */ -#line 1210 "../parser/Grammar.y" +#line 1219 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 296: - -/* Line 1455 of yacc.c */ -#line 1211 "../parser/Grammar.y" +#line 1220 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 297: - -/* Line 1455 of yacc.c */ -#line 1215 "../parser/Grammar.y" +#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 1216 "../parser/Grammar.y" +#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 1221 "../parser/Grammar.y" +#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); (yyval.sourceElements).m_varDeclarations = (yyvsp[(1) - (1)].statementNode).m_varDeclarations; @@ -4839,9 +4439,7 @@ yyreduce: break; case 300: - -/* Line 1455 of yacc.c */ -#line 1228 "../parser/Grammar.y" +#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); (yyval.sourceElements).m_funcDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (2)].statementNode).m_funcDeclarations); @@ -4851,261 +4449,188 @@ yyreduce: break; case 304: - -/* Line 1455 of yacc.c */ -#line 1242 "../parser/Grammar.y" +#line 1251 "../parser/Grammar.y" { ;} break; case 305: - -/* Line 1455 of yacc.c */ -#line 1243 "../parser/Grammar.y" +#line 1252 "../parser/Grammar.y" { ;} break; case 306: - -/* Line 1455 of yacc.c */ -#line 1244 "../parser/Grammar.y" - { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} +#line 1253 "../parser/Grammar.y" + { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;} break; case 307: - -/* Line 1455 of yacc.c */ -#line 1245 "../parser/Grammar.y" - { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} +#line 1254 "../parser/Grammar.y" + { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;} break; case 308: - -/* Line 1455 of yacc.c */ -#line 1249 "../parser/Grammar.y" +#line 1258 "../parser/Grammar.y" { ;} break; case 309: - -/* Line 1455 of yacc.c */ -#line 1250 "../parser/Grammar.y" +#line 1259 "../parser/Grammar.y" { ;} break; case 310: - -/* Line 1455 of yacc.c */ -#line 1251 "../parser/Grammar.y" +#line 1260 "../parser/Grammar.y" { ;} break; case 311: - -/* Line 1455 of yacc.c */ -#line 1252 "../parser/Grammar.y" +#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 1253 "../parser/Grammar.y" +#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 1263 "../parser/Grammar.y" +#line 1272 "../parser/Grammar.y" { ;} break; case 317: - -/* Line 1455 of yacc.c */ -#line 1264 "../parser/Grammar.y" +#line 1273 "../parser/Grammar.y" { ;} break; case 318: - -/* Line 1455 of yacc.c */ -#line 1266 "../parser/Grammar.y" +#line 1275 "../parser/Grammar.y" { ;} break; case 322: - -/* Line 1455 of yacc.c */ -#line 1273 "../parser/Grammar.y" +#line 1282 "../parser/Grammar.y" { ;} break; case 517: - -/* Line 1455 of yacc.c */ -#line 1641 "../parser/Grammar.y" +#line 1650 "../parser/Grammar.y" { ;} break; case 518: - -/* Line 1455 of yacc.c */ -#line 1642 "../parser/Grammar.y" +#line 1651 "../parser/Grammar.y" { ;} break; case 520: - -/* Line 1455 of yacc.c */ -#line 1647 "../parser/Grammar.y" +#line 1656 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 521: - -/* Line 1455 of yacc.c */ -#line 1651 "../parser/Grammar.y" +#line 1660 "../parser/Grammar.y" { ;} break; case 522: - -/* Line 1455 of yacc.c */ -#line 1652 "../parser/Grammar.y" +#line 1661 "../parser/Grammar.y" { ;} break; case 525: - -/* Line 1455 of yacc.c */ -#line 1658 "../parser/Grammar.y" +#line 1667 "../parser/Grammar.y" { ;} break; case 526: - -/* Line 1455 of yacc.c */ -#line 1659 "../parser/Grammar.y" +#line 1668 "../parser/Grammar.y" { ;} break; case 530: - -/* Line 1455 of yacc.c */ -#line 1666 "../parser/Grammar.y" +#line 1675 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 533: - -/* Line 1455 of yacc.c */ -#line 1675 "../parser/Grammar.y" +#line 1684 "../parser/Grammar.y" { ;} break; case 534: - -/* Line 1455 of yacc.c */ -#line 1676 "../parser/Grammar.y" +#line 1685 "../parser/Grammar.y" { ;} break; case 539: - -/* Line 1455 of yacc.c */ -#line 1693 "../parser/Grammar.y" +#line 1702 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 555: - -/* Line 1455 of yacc.c */ -#line 1724 "../parser/Grammar.y" +#line 1733 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 557: - -/* Line 1455 of yacc.c */ -#line 1726 "../parser/Grammar.y" +#line 1735 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 559: - -/* Line 1455 of yacc.c */ -#line 1731 "../parser/Grammar.y" +#line 1740 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 561: - -/* Line 1455 of yacc.c */ -#line 1733 "../parser/Grammar.y" +#line 1742 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 563: - -/* Line 1455 of yacc.c */ -#line 1738 "../parser/Grammar.y" +#line 1747 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 565: - -/* Line 1455 of yacc.c */ -#line 1740 "../parser/Grammar.y" +#line 1749 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 568: - -/* Line 1455 of yacc.c */ -#line 1752 "../parser/Grammar.y" +#line 1761 "../parser/Grammar.y" { ;} break; case 569: - -/* Line 1455 of yacc.c */ -#line 1753 "../parser/Grammar.y" +#line 1762 "../parser/Grammar.y" { ;} break; case 578: - -/* Line 1455 of yacc.c */ -#line 1777 "../parser/Grammar.y" +#line 1786 "../parser/Grammar.y" { ;} break; case 580: - -/* Line 1455 of yacc.c */ -#line 1782 "../parser/Grammar.y" +#line 1791 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 585: - -/* Line 1455 of yacc.c */ -#line 1793 "../parser/Grammar.y" +#line 1802 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 592: - -/* Line 1455 of yacc.c */ -#line 1809 "../parser/Grammar.y" +#line 1818 "../parser/Grammar.y" { ;} break; - -/* Line 1455 of yacc.c */ -#line 5109 "JavaScriptCore/tmp/../generated/Grammar.tab.c" +/* Line 1267 of yacc.c. */ +#line 4634 "JavaScriptCore/tmp/../generated/Grammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -5181,7 +4706,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -5198,7 +4723,7 @@ yyerrlab: } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; @@ -5256,11 +4781,14 @@ 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 lookahead. YYLOC is available though. */ + the look-ahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; @@ -5285,7 +4813,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined(yyoverflow) || YYERROR_VERBOSE +#ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -5296,7 +4824,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEMPTY) + if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); /* Do not reclaim the symbols of the rule which action triggered @@ -5322,31 +4850,31 @@ yyreturn: } +#line 1834 "../parser/Grammar.y" -/* Line 1675 of yacc.c */ -#line 1825 "../parser/Grammar.y" +#undef GLOBAL_DATA -static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) +static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) { if (!loc->isLocation()) - return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot); + return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(loc); if (op == OpEqual) { - AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); - SET_EXCEPTION_LOCATION(node, start, divot, end); + AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments); + setExceptionLocation(node, start, divot, end); return node; } else - return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); + return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); else { - ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } @@ -5354,117 +4882,117 @@ static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Oper ASSERT(loc->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); + return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); - ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PrefixDotNode* node = new (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->startOffset()); return node; } -static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PostfixDotNode* node = new (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) { CodeFeatures features = func.m_features | args.m_features; int numConstants = func.m_numConstants + args.m_numConstants; if (!func.m_node->isLocation()) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); if (func.m_node->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node); const Identifier& identifier = resolve->identifier(); - if (identifier == GLOBAL_DATA->propertyNames->eval) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); + if (identifier == globalData->propertyNames->eval) + return createNodeInfo<ExpressionNode*>(new (globalData) EvalFunctionCallNode(globalData, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallResolveNode(globalData, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); } if (func.m_node->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node); - FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); + FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } ASSERT(func.m_node->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node); FunctionCallDotNode* node; - if (dot->identifier() == GLOBAL_DATA->propertyNames->call) - node = new (GLOBAL_DATA) CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - else if (dot->identifier() == GLOBAL_DATA->propertyNames->apply) - node = new (GLOBAL_DATA) ApplyFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + if (dot->identifier() == globalData->propertyNames->call) + node = new (globalData) CallFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + else if (dot->identifier() == globalData->propertyNames->apply) + node = new (globalData) ApplyFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); else - node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } -static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeTypeOfNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier()); + return new (globalData) TypeOfResolveNode(globalData, resolve->identifier()); } - return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr); + return new (globalData) TypeOfValueNode(globalData, expr); } -static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end) +static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr); + return new (globalData) DeleteValueNode(globalData, expr); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); + return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); } -static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) { PropertyNode::Type type; if (getOrSet == "get") @@ -5473,10 +5001,10 @@ static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Ident type = PropertyNode::Setter; else return 0; - return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type); + return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type); } -static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) +static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n) { if (n->isNumber()) { NumberNode* number = static_cast<NumberNode*>(n); @@ -5487,92 +5015,92 @@ static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) } } - return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n); + return new (globalData) NegateNode(globalData, n); } -static NumberNode* makeNumberNode(void* globalPtr, double d) +static NumberNode* makeNumberNode(JSGlobalData* globalData, double d) { - return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d); + return new (globalData) NumberNode(globalData, d); } -static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isNumber()) - return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value())); - return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr); + return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value())); + return new (globalData) BitwiseNotNode(globalData, expr); } -static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2); + return new (globalData) UnaryPlusNode(globalData, expr2); if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1); + return new (globalData) UnaryPlusNode(globalData, expr1); - return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); + return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); + return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); + return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments); } -/* called by yyparse on error */ -int yyerror(const char *) +// Called by yyparse on error. +int yyerror(const char*) { return 1; } -/* may we automatically insert a semicolon ? */ +// May we automatically insert a semicolon? static bool allowAutomaticSemicolon(Lexer& lexer, int yychar) { return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator(); } -static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init) +static ExpressionNode* combineCommaNodes(JSGlobalData* globalData, ExpressionNode* list, ExpressionNode* init) { if (!list) return init; @@ -5580,18 +5108,16 @@ static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, static_cast<CommaNode*>(list)->append(init); return list; } - return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init); + return new (globalData) CommaNode(globalData, list, init); } // We turn variable declarations into either assignments or empty // statements (which later get stripped out), because the actual // declaration work is hoisted up to the start of the function body -static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr) +static StatementNode* makeVarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) { if (!expr) - return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA); - return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr); + return new (globalData) EmptyStatementNode(globalData); + return new (globalData) VarStatementNode(globalData, expr); } -#undef GLOBAL_DATA - diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h index 847624f..1fdb035 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h @@ -1,23 +1,24 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + + 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 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>. */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -28,11 +29,10 @@ 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,19 +104,81 @@ 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 155 "../parser/Grammar.y" - int intValue; double doubleValue; - Identifier* ident; + const Identifier* ident; // expression subtrees ExpressionNodeInfo expressionNode; @@ -143,15 +205,13 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; - - - -/* Line 1676 of yacc.c */ -#line 151 "JavaScriptCore/tmp/../generated/Grammar.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 1489 of yacc.c. */ +#line 211 "JavaScriptCore/tmp/../generated/Grammar.tab.h" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif @@ -170,4 +230,3 @@ typedef struct YYLTYPE #endif - diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h index 767c262..b9fa484 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h @@ -40,7 +40,8 @@ namespace JSC { , m_exception(exception) , m_globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : function->scope().node()->globalObject()) { - m_closure = m_interpreter->prepareForRepeatCall(function->body(), callFrame, function, argCount, function->scope().node(), exception); + ASSERT(!function->isHostFunction()); + m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope().node(), exception); m_valid = !*exception; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h index 75de082..b04e1c1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h @@ -105,7 +105,7 @@ namespace JSC { Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); } Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); } - void setCalleeArguments(Arguments* arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; } + void setCalleeArguments(JSValue arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; } void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; } void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; } @@ -118,10 +118,10 @@ namespace JSC { setScopeChain(scopeChain); setCallerFrame(callerFrame); this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. - this[RegisterFile::ReturnValueRegister] = returnValueRegister; + this[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister); setArgumentCount(argc); // original argument count (for the sake of the "arguments" object) setCallee(callee); - setCalleeArguments(0); + setCalleeArguments(JSValue()); } // Read a register from the codeframe (or constant from the CodeBlock). @@ -135,7 +135,7 @@ namespace JSC { CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } private: - void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = count; } + void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = Register::withInt(count); } void setCallee(JSObject* callee) { this[RegisterFile::Callee] = callee; } void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrameClosure.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrameClosure.h index 0e14ced..a301060 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrameClosure.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrameClosure.h @@ -32,7 +32,7 @@ struct CallFrameClosure { CallFrame* oldCallFrame; CallFrame* newCallFrame; JSFunction* function; - FunctionBodyNode* functionBody; + FunctionExecutable* functionExecutable; JSGlobalData* globalData; Register* oldEnd; ScopeChainNode* scopeChain; @@ -49,7 +49,7 @@ struct CallFrameClosure { void resetCallFrame() { newCallFrame->setScopeChain(scopeChain); - newCallFrame->setCalleeArguments(0); + newCallFrame->setCalleeArguments(JSValue()); for (int i = providedParams; i < expectedParams; ++i) newCallFrame[i - RegisterFile::CallFrameHeaderSize - expectedParams] = jsUndefined(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp index 42e0b05..7d3a84d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp @@ -58,6 +58,7 @@ #include "RegExpPrototype.h" #include "Register.h" #include "SamplingTool.h" +#include <limits.h> #include <stdio.h> #include <wtf/Threading.h> @@ -65,10 +66,6 @@ #include "JIT.h" #endif -#if ENABLE(ASSEMBLER) -#include "AssemblerBuffer.h" -#endif - #ifdef QT_BUILD_SCRIPT_LIB #include "bridge/qscriptobject_p.h" #endif @@ -176,7 +173,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* PropertySlot slot(globalObject); if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); - if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) { + if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { if (vPC[4].u.structure) vPC[4].u.structure->deref(); globalObject->structure()->ref(); @@ -357,15 +354,14 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON); if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; - - + ScopeChainNode* scopeChain = callFrame->scopeChain(); CodeBlock* codeBlock = callFrame->codeBlock(); - RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue); + RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue); JSValue result = jsUndefined(); - if (evalNode) - result = callFrame->globalData().interpreter->execute(evalNode.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue); + if (eval) + result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue); return result; } @@ -388,67 +384,92 @@ void Interpreter::dumpCallFrame(CallFrame* callFrame) void Interpreter::dumpRegisters(CallFrame* callFrame) { printf("Register frame: \n\n"); - printf("----------------------------------------------------\n"); - printf(" use | address | value \n"); - printf("----------------------------------------------------\n"); + printf("-----------------------------------------------------------------------------\n"); + printf(" use | address | value \n"); + printf("-----------------------------------------------------------------------------\n"); CodeBlock* codeBlock = callFrame->codeBlock(); RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile(); const Register* it; const Register* end; + JSValue v; if (codeBlock->codeType() == GlobalCode) { it = registerFile->lastGlobal(); end = it + registerFile->numGlobals(); while (it != end) { - printf("[global var] | %10p | %10p \n", it, (*it).v()); + v = (*it).jsValue(); +#if USE(JSVALUE32_64) + printf("[global var] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); +#else + printf("[global var] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); +#endif ++it; } - printf("----------------------------------------------------\n"); + printf("-----------------------------------------------------------------------------\n"); } it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->m_numParameters; - printf("[this] | %10p | %10p \n", it, (*it).v()); ++it; + v = (*it).jsValue(); +#if USE(JSVALUE32_64) + printf("[this] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it; +#else + printf("[this] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it; +#endif end = it + max(codeBlock->m_numParameters - 1, 0); // - 1 to skip "this" if (it != end) { do { - printf("[param] | %10p | %10p \n", it, (*it).v()); + v = (*it).jsValue(); +#if USE(JSVALUE32_64) + printf("[param] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); +#else + printf("[param] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); +#endif ++it; } while (it != end); } - printf("----------------------------------------------------\n"); - - printf("[CodeBlock] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[ScopeChain] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[CallerRegisters] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[ReturnPC] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[ReturnValueRegister] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[ArgumentCount] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[Callee] | %10p | %10p \n", it, (*it).v()); ++it; - printf("[OptionalCalleeArguments] | %10p | %10p \n", it, (*it).v()); ++it; - printf("----------------------------------------------------\n"); + printf("-----------------------------------------------------------------------------\n"); + printf("[CodeBlock] | %10p | %p \n", it, (*it).codeBlock()); ++it; + printf("[ScopeChain] | %10p | %p \n", it, (*it).scopeChain()); ++it; + printf("[CallerRegisters] | %10p | %d \n", it, (*it).i()); ++it; + printf("[ReturnPC] | %10p | %p \n", it, (*it).vPC()); ++it; + printf("[ReturnValueRegister] | %10p | %d \n", it, (*it).i()); ++it; + printf("[ArgumentCount] | %10p | %d \n", it, (*it).i()); ++it; + printf("[Callee] | %10p | %p \n", it, (*it).function()); ++it; + printf("[OptionalCalleeArguments] | %10p | %p \n", it, (*it).arguments()); ++it; + printf("-----------------------------------------------------------------------------\n"); int registerCount = 0; end = it + codeBlock->m_numVars; if (it != end) { do { - printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v()); + v = (*it).jsValue(); +#if USE(JSVALUE32_64) + printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v)); +#else + printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v)); +#endif ++it; ++registerCount; } while (it != end); } - printf("----------------------------------------------------\n"); + printf("-----------------------------------------------------------------------------\n"); end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars; if (it != end) { do { - printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v()); + v = (*it).jsValue(); +#if USE(JSVALUE32_64) + printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v)); +#else + printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v)); +#endif ++it; ++registerCount; } while (it != end); } - printf("----------------------------------------------------\n"); + printf("-----------------------------------------------------------------------------\n"); } #endif @@ -472,24 +493,24 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); if (callFrame->callee()) { - debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine()); + debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine()); #ifdef QT_BUILD_SCRIPT_LIB - debugger->functionExit(exceptionValue, codeBlock->ownerNode()->sourceID()); + debugger->functionExit(exceptionValue, codeBlock->ownerExecutable()->sourceID()); #endif } else - debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine()); + debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine()); } if (Profiler* profiler = *Profiler::enabledProfilerReference()) { if (callFrame->callee()) profiler->didExecute(callFrame, callFrame->callee()); else - profiler->didExecute(callFrame, codeBlock->ownerNode()->sourceURL(), codeBlock->ownerNode()->lineNo()); + profiler->didExecute(callFrame, codeBlock->ownerExecutable()->sourceURL(), codeBlock->ownerExecutable()->lineNo()); } // If this call frame created an activation or an 'arguments' object, tear it off. if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) { - while (!scopeChain->object->isObject(&JSActivation::info)) + while (!scopeChain->object->inherits(&JSActivation::info)) scopeChain = scopeChain->pop(); static_cast<JSActivation*>(scopeChain->object)->copyRegisters(callFrame->optionalCalleeArguments()); } else if (Arguments* arguments = callFrame->optionalCalleeArguments()) { @@ -540,8 +561,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete); } else exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_LINENUMBER_PROPERTYNAME), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)), ReadOnly | DontDelete); - exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode()->sourceID()), ReadOnly | DontDelete); - exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_FILENAME_PROPERTYNAME), jsOwnedString(callFrame, codeBlock->ownerNode()->sourceURL()), ReadOnly | DontDelete); + exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerExecutable()->sourceID()), ReadOnly | DontDelete); + exception->putWithAttributes(callFrame, Identifier(callFrame, JSC_ERROR_FILENAME_PROPERTYNAME), jsOwnedString(callFrame, codeBlock->ownerExecutable()->sourceURL()), ReadOnly | DontDelete); } if (exception->isWatchdogException()) { @@ -556,7 +577,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV Debugger* debugger = callFrame->dynamicGlobalObject()->debugger(); if (debugger) { DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); - debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)); + debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)); } // If we throw in the middle of a call instruction, we need to notify @@ -597,7 +618,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV } } if (debugger) - debugger->exceptionThrow(DebuggerCallFrame(callFrame, exceptionValue), codeBlock->ownerNode()->sourceID(), hasHandler); + debugger->exceptionThrow(DebuggerCallFrame(callFrame, exceptionValue), codeBlock->ownerExecutable()->sourceID(), hasHandler); #endif while (!(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { @@ -618,7 +639,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV return handler; } -JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception) +JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception) { ASSERT(!scopeChain->globalData->exception); @@ -629,7 +650,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco } } - CodeBlock* codeBlock = &programNode->bytecode(scopeChain); + CodeBlock* codeBlock = &program->bytecode(callFrame, scopeChain); Register* oldEnd = m_registerFile.end(); Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; @@ -653,7 +674,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco Profiler** profiler = Profiler::enabledProfilerReference(); if (*profiler) - (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo()); + (*profiler)->willExecute(newCallFrame, program->sourceURL(), program->lineNo()); JSValue result; { @@ -661,7 +682,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco m_reentryDepth++; #if ENABLE(JIT) - result = programNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); + result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); #else result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); #endif @@ -669,7 +690,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco } if (*profiler) - (*profiler)->didExecute(callFrame, programNode->sourceURL(), programNode->lineNo()); + (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo()); if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject) lastGlobalObject->copyGlobalsTo(m_registerFile); @@ -679,7 +700,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco return result; } -JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception) +JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception) { ASSERT(!scopeChain->globalData->exception); @@ -707,7 +728,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call for (ArgList::const_iterator it = args.begin(); it != end; ++it) newCallFrame->r(++dst) = *it; - CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain); + CodeBlock* codeBlock = &functionExecutable->bytecode(callFrame, scopeChain); newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); if (UNLIKELY(!newCallFrame)) { *exception = createStackOverflowError(callFrame); @@ -727,7 +748,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call m_reentryDepth++; #if ENABLE(JIT) - result = functionBodyNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); + result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); #else result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); #endif @@ -741,7 +762,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call return result; } -CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception) +CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception) { ASSERT(!scopeChain->globalData->exception); @@ -765,7 +786,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod for (int i = 0; i < argc; ++i) newCallFrame->r(++dst) = jsUndefined(); - CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain); + CodeBlock* codeBlock = &FunctionExecutable->bytecode(callFrame, scopeChain); newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); if (UNLIKELY(!newCallFrame)) { *exception = createStackOverflowError(callFrame); @@ -775,10 +796,10 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod // a 0 codeBlock indicates a built-in caller newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function); #if ENABLE(JIT) - functionBodyNode->jitCode(scopeChain); + FunctionExecutable->jitCode(newCallFrame, scopeChain); #endif - CallFrameClosure result = { callFrame, newCallFrame, function, functionBodyNode, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc }; + CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc }; return result; } @@ -795,7 +816,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception) m_reentryDepth++; #if ENABLE(JIT) - result = closure.functionBody->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception); + result = closure.functionExecutable->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception); #else result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception); #endif @@ -812,12 +833,12 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure) m_registerFile.shrink(closure.oldEnd); } -JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception) +JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception) { - return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception); + return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(callFrame, scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception); } -JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception) +JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception) { ASSERT(!scopeChain->globalData->exception); @@ -830,7 +851,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject()); - EvalCodeBlock* codeBlock = &evalNode->bytecode(scopeChain); + EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain); JSVariableObject* variableObject; for (ScopeChainNode* node = scopeChain; ; node = node->next) { @@ -845,21 +866,20 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* BatchedTransitionOptimizer optimizer(variableObject); - const DeclarationStacks::VarStack& varStack = codeBlock->ownerNode()->varStack(); - DeclarationStacks::VarStack::const_iterator varStackEnd = varStack.end(); - for (DeclarationStacks::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) { - const Identifier& ident = (*it).first; + unsigned numVariables = codeBlock->numVariables(); + for (unsigned i = 0; i < numVariables; ++i) { + const Identifier& ident = codeBlock->variable(i); if (!variableObject->hasProperty(callFrame, ident)) { PutPropertySlot slot; variableObject->put(callFrame, ident, jsUndefined(), slot); } } - const DeclarationStacks::FunctionStack& functionStack = codeBlock->ownerNode()->functionStack(); - DeclarationStacks::FunctionStack::const_iterator functionStackEnd = functionStack.end(); - for (DeclarationStacks::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) { + int numFunctions = codeBlock->numberOfFunctionDecls(); + for (int i = 0; i < numFunctions; ++i) { + FunctionExecutable* function = codeBlock->functionDecl(i); PutPropertySlot slot; - variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(callFrame, scopeChain), slot); + variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot); } } @@ -882,7 +902,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* Profiler** profiler = Profiler::enabledProfilerReference(); if (*profiler) - (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo()); + (*profiler)->willExecute(newCallFrame, eval->sourceURL(), eval->lineNo()); JSValue result; { @@ -890,7 +910,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* m_reentryDepth++; #if ENABLE(JIT) - result = evalNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); + result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception); #else result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); #endif @@ -898,7 +918,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* } if (*profiler) - (*profiler)->didExecute(callFrame, evalNode->sourceURL(), evalNode->lineNo()); + (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo()); m_registerFile.shrink(oldEnd); return result; @@ -912,22 +932,22 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook switch (debugHookID) { case DidEnterCallFrame: - debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine); + debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); return; case WillLeaveCallFrame: - debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine); + debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); return; case WillExecuteStatement: - debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine, column); + debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column); return; case WillExecuteProgram: - debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine); + debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); return; case DidExecuteProgram: - debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine); + debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); return; case DidReachBreakpoint: - debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine, column); + debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column); return; } } @@ -963,7 +983,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { vPC[0] = getOpcode(op_put_by_id_generic); return; } @@ -1050,7 +1070,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* Structure* structure = asCell(baseValue)->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { vPC[0] = getOpcode(op_get_by_id_generic); return; } @@ -1145,7 +1165,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } #if ENABLE(JIT) - // Currently with CTI enabled we never interpret functions + // Mixing Interpreter + JIT is not supported. ASSERT_NOT_REACHED(); #endif #if !USE(INTERPRETER) @@ -1184,7 +1204,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi tickCount = globalData->timeoutChecker->ticksUntilNextCheck(); \ CHECK_FOR_EXCEPTION(); \ } - + #if ENABLE(OPCODE_SAMPLING) #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC) #else @@ -1276,8 +1296,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame->r(dst) = JSFastMath::equal(src1, src2); + if (src1.isInt32() && src2.isInt32()) + callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32()); else { JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); @@ -1316,8 +1336,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame->r(dst) = JSFastMath::notEqual(src1, src2); + if (src1.isInt32() && src2.isInt32()) + callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32()); else { JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); @@ -1418,8 +1438,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int srcDst = (++vPC)->u.operand; JSValue v = callFrame->r(srcDst).jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) - callFrame->r(srcDst) = JSValue(JSFastMath::incImmediateNumber(v)); + if (v.isInt32() && v.asInt32() < INT_MAX) + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); else { JSValue result = jsNumber(callFrame, v.toNumber(callFrame) + 1); CHECK_FOR_EXCEPTION(); @@ -1437,8 +1457,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int srcDst = (++vPC)->u.operand; JSValue v = callFrame->r(srcDst).jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) - callFrame->r(srcDst) = JSValue(JSFastMath::decImmediateNumber(v)); + if (v.isInt32() && v.asInt32() > INT_MIN) + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); else { JSValue result = jsNumber(callFrame, v.toNumber(callFrame) - 1); CHECK_FOR_EXCEPTION(); @@ -1458,14 +1478,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int srcDst = (++vPC)->u.operand; JSValue v = callFrame->r(srcDst).jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) { + if (v.isInt32() && v.asInt32() < INT_MAX) { + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); callFrame->r(dst) = v; - callFrame->r(srcDst) = JSValue(JSFastMath::incImmediateNumber(v)); } else { JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); + callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() + 1); callFrame->r(dst) = number; - callFrame->r(srcDst) = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() + 1)); } ++vPC; @@ -1481,14 +1501,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int srcDst = (++vPC)->u.operand; JSValue v = callFrame->r(srcDst).jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(v)) { + if (v.isInt32() && v.asInt32() > INT_MIN) { + callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); callFrame->r(dst) = v; - callFrame->r(srcDst) = JSValue(JSFastMath::decImmediateNumber(v)); } else { JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); + callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() - 1); callFrame->r(dst) = number; - callFrame->r(srcDst) = JSValue(jsNumber(callFrame, number.uncheckedGetNumber() - 1)); } ++vPC; @@ -1524,16 +1544,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); - ++vPC; - double v; - if (src.getNumber(v)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, -v)); + if (src.isInt32() && src.asInt32()) + callFrame->r(dst) = jsNumber(callFrame, -src.asInt32()); else { JSValue result = jsNumber(callFrame, -src.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } + ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_add) { @@ -1546,8 +1565,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) - callFrame->r(dst) = JSValue(JSFastMath::addImmediateNumbers(src1, src2)); + if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32()); else { JSValue result = jsAdd(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -1565,17 +1584,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - double left; - double right; - if (JSValue::areBothInt32Fast(src1, src2)) { - int32_t left = src1.getInt32Fast(); - int32_t right = src2.getInt32Fast(); - if ((left | right) >> 15 == 0) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left * right)); - else - callFrame->r(dst) = JSValue(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right))); - } else if (src1.getNumber(left) && src2.getNumber(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left * right)); + if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32()); else { JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); @@ -1595,16 +1605,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); - double left; - double right; - if (dividend.getNumber(left) && divisor.getNumber(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left / right)); - else { - JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); - CHECK_FOR_EXCEPTION(); - callFrame->r(dst) = result; - } - ++vPC; + + JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); + CHECK_FOR_EXCEPTION(); + callFrame->r(dst) = result; + + vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mod) { @@ -1615,24 +1621,22 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi remainder in register dst. */ int dst = (++vPC)->u.operand; - int dividend = (++vPC)->u.operand; - int divisor = (++vPC)->u.operand; - - JSValue dividendValue = callFrame->r(dividend).jsValue(); - JSValue divisorValue = callFrame->r(divisor).jsValue(); + JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); + JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); - if (JSValue::areBothInt32Fast(dividendValue, divisorValue) && divisorValue != jsNumber(callFrame, 0)) { - // We expect the result of the modulus of a number that was representable as an int32 to also be representable - // as an int32. - JSValue result = JSValue::makeInt32Fast(dividendValue.getInt32Fast() % divisorValue.getInt32Fast()); + if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) { + JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32()); ASSERT(result); callFrame->r(dst) = result; ++vPC; NEXT_INSTRUCTION(); } - double d = dividendValue.toNumber(callFrame); - JSValue result = jsNumber(callFrame, fmod(d, divisorValue.toNumber(callFrame))); + // Conversion to double must happen outside the call to fmod since the + // order of argument evaluation is not guaranteed. + double d1 = dividend.toNumber(callFrame); + double d2 = divisor.toNumber(callFrame); + JSValue result = jsNumber(callFrame, fmod(d1, d2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; ++vPC; @@ -1648,12 +1652,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - double left; - double right; - if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) - callFrame->r(dst) = JSValue(JSFastMath::subImmediateNumbers(src1, src2)); - else if (src1.getNumber(left) && src2.getNumber(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left - right)); + if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32()); else { JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); @@ -1672,12 +1672,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t left; - uint32_t right; - if (JSValue::areBothInt32Fast(val, shift)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f))); - else if (val.numberToInt32(left) && shift.numberToUInt32(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left << (right & 0x1f))); + + if (val.isInt32() && shift.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f)); else { JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); @@ -1697,12 +1694,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t left; - uint32_t right; - if (JSFastMath::canDoFastRshift(val, shift)) - callFrame->r(dst) = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift)); - else if (val.numberToInt32(left) && shift.numberToUInt32(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left >> (right & 0x1f))); + + if (val.isInt32() && shift.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); else { JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); @@ -1722,8 +1716,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); - if (JSFastMath::canDoFastUrshift(val, shift)) - callFrame->r(dst) = JSValue(JSFastMath::rightShiftImmediateNumbers(val, shift)); + if (val.isUInt32() && shift.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); else { JSValue result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); @@ -1743,12 +1737,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame->r(dst) = JSValue(JSFastMath::andImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left & right)); + if (src1.isInt32() && src2.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32()); else { JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); @@ -1768,12 +1758,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame->r(dst) = JSValue(JSFastMath::xorImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left ^ right)); + if (src1.isInt32() && src2.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32()); else { JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); @@ -1793,12 +1779,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t left; - int32_t right; - if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) - callFrame->r(dst) = JSValue(JSFastMath::orImmediateNumbers(src1, src2)); - else if (src1.numberToInt32(left) && src2.numberToInt32(right)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, left | right)); + if (src1.isInt32() && src2.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32()); else { JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); @@ -1816,9 +1798,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ int dst = (++vPC)->u.operand; JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); - int32_t value; - if (src.numberToInt32(value)) - callFrame->r(dst) = JSValue(jsNumber(callFrame, ~value)); + if (src.isInt32()) + callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32()); else { JSValue result = jsNumber(callFrame, ~src.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); @@ -2152,27 +2133,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi vPC += 4; NEXT_INSTRUCTION(); } - DEFINE_OPCODE(op_resolve_func) { - /* resolve_func baseDst(r) funcDst(r) property(id) - - Searches the scope chain for an object containing - identifier property, and if one is found, writes the - appropriate object to use as "this" when calling its - properties to register baseDst; and the retrieved property - value to register propDst. If the property is not found, - raises an exception. - - This differs from resolve_with_base, because the - global this value will be substituted for activations or - the global object, which is the right behavior for function - calls but not for other property lookup. - */ - if (UNLIKELY(!resolveBaseAndFunc(callFrame, vPC, exceptionValue))) - goto vm_throw; - - vPC += 4; - NEXT_INSTRUCTION(); - } DEFINE_OPCODE(op_get_by_id) { /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n) @@ -2353,7 +2313,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(isJSArray(globalData, baseValue))) { int dst = vPC[1].u.operand; - callFrame->r(dst) = JSValue(jsNumber(callFrame, asArray(baseValue)->length())); + callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length()); vPC += 8; NEXT_INSTRUCTION(); } @@ -2373,7 +2333,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue baseValue = callFrame->r(base).jsValue(); if (LIKELY(isJSString(globalData, baseValue))) { int dst = vPC[1].u.operand; - callFrame->r(dst) = JSValue(jsNumber(callFrame, asString(baseValue)->value().size())); + callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size()); vPC += 8; NEXT_INSTRUCTION(); } @@ -2551,8 +2511,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue result; - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSArray(globalData, baseValue)) { JSArray* jsArray = asArray(baseValue); if (jsArray->canGetIndex(i)) @@ -2593,8 +2553,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue baseValue = callFrame->r(base).jsValue(); JSValue subscript = callFrame->r(property).jsValue(); - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSArray(globalData, baseValue)) { JSArray* jsArray = asArray(baseValue); if (jsArray->canSetIndex(i)) @@ -2605,8 +2565,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSByteArray* jsByteArray = asByteArray(baseValue); double dValue = 0; JSValue jsValue = callFrame->r(value).jsValue(); - if (jsValue.isInt32Fast()) - jsByteArray->setIndex(i, jsValue.getInt32Fast()); + if (jsValue.isInt32()) + jsByteArray->setIndex(i, jsValue.asInt32()); else if (jsValue.getNumber(dValue)) jsByteArray->setIndex(i, dValue); else @@ -2926,8 +2886,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int tableIndex = (++vPC)->u.operand; int defaultOffset = (++vPC)->u.operand; JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); - if (scrutinee.isInt32Fast()) - vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset); + if (scrutinee.isInt32()) + vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); else { double value; int32_t intValue; @@ -2990,7 +2950,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = (++vPC)->u.operand; int func = (++vPC)->u.operand; - callFrame->r(dst) = callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain()); + callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain())); ++vPC; NEXT_INSTRUCTION(); @@ -3004,9 +2964,24 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi puts the result in register dst. */ int dst = (++vPC)->u.operand; - int func = (++vPC)->u.operand; + int funcIndex = (++vPC)->u.operand; + + FunctionExecutable* function = callFrame->codeBlock()->functionExpr(funcIndex); + JSFunction* func = function->make(callFrame, callFrame->scopeChain()); - callFrame->r(dst) = callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain()); + /* + The Identifier in a FunctionExpression can be referenced from inside + the FunctionExpression's FunctionBody to allow the function to call + itself recursively. However, unlike in a FunctionDeclaration, the + Identifier in a FunctionExpression cannot be referenced from and + does not affect the scope enclosing the FunctionExpression. + */ + if (!function->name().isNull()) { + JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); + func->scope().push(functionScopeObject); + } + + callFrame->r(dst) = JSValue(func); ++vPC; NEXT_INSTRUCTION(); @@ -3072,8 +3047,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callType == CallTypeJS) { ScopeChainNode* callDataScopeChain = callData.js.scopeChain; - FunctionBodyNode* functionBodyNode = callData.js.functionBody; - CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain); + CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain); CallFrame* previousCallFrame = callFrame; @@ -3114,7 +3088,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame->r(dst) = JSValue(returnValue); + callFrame->r(dst) = returnValue; vPC += 5; NEXT_INSTRUCTION(); @@ -3139,7 +3113,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi exceptionValue = createStackOverflowError(callFrame); goto vm_throw; } - int32_t expectedParams = static_cast<JSFunction*>(callFrame->callee())->body()->parameterCount(); + ASSERT(!callFrame->callee()->isHostFunction()); + int32_t expectedParams = static_cast<JSFunction*>(callFrame->callee())->jsExecutable()->parameterCount(); int32_t inplaceArgs = min(argCount, expectedParams); int32_t i = 0; Register* argStore = callFrame->registers() + argsOffset; @@ -3197,7 +3172,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } } CHECK_FOR_EXCEPTION(); - callFrame->r(argCountDst) = argCount + 1; + callFrame->r(argCountDst) = Register::withInt(argCount + 1); ++vPC; NEXT_INSTRUCTION(); } @@ -3226,8 +3201,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callType == CallTypeJS) { ScopeChainNode* callDataScopeChain = callData.js.scopeChain; - FunctionBodyNode* functionBodyNode = callData.js.functionBody; - CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain); + CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain); CallFrame* previousCallFrame = callFrame; @@ -3268,7 +3242,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - callFrame->r(dst) = JSValue(returnValue); + callFrame->r(dst) = returnValue; vPC += 5; NEXT_INSTRUCTION(); @@ -3314,6 +3288,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain()); + if (callFrame->optionalCalleeArguments()) callFrame->optionalCalleeArguments()->copyRegisters(); @@ -3354,7 +3329,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callFrame->hasHostCallFrameFlag()) return returnValue; - callFrame->r(dst) = JSValue(returnValue); + callFrame->r(dst) = returnValue; NEXT_INSTRUCTION(); } @@ -3398,8 +3373,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(i) = jsUndefined(); int dst = (++vPC)->u.operand; - JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode())); - callFrame->r(dst) = activation; + JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable())); + callFrame->r(dst) = JSValue(activation); callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); ++vPC; @@ -3450,7 +3425,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (!callFrame->r(RegisterFile::ArgumentsRegister).jsValue()) { Arguments* arguments = new (globalData) Arguments(callFrame); callFrame->setCalleeArguments(arguments); - callFrame->r(RegisterFile::ArgumentsRegister) = arguments; + callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } ++vPC; NEXT_INSTRUCTION(); @@ -3484,8 +3459,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (constructType == ConstructTypeJS) { ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; - FunctionBodyNode* functionBodyNode = constructData.js.functionBody; - CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain); + CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecode(callFrame, callDataScopeChain); Structure* structure; JSValue prototype = callFrame->r(proto).jsValue(); @@ -3703,7 +3677,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Debugger* debugger = callFrame->dynamicGlobalObject()->debugger(); if (debugger) { DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); - debugger->exceptionCatch(debuggerCallFrame, codeBlock->ownerNode()->sourceID()); + debugger->exceptionCatch(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID()); } #endif @@ -3750,7 +3724,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int message = (++vPC)->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->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL())); + 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; NEXT_INSTRUCTION(); @@ -3813,7 +3787,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSObject* baseObj = asObject(callFrame->r(base).jsValue()); Identifier& ident = callFrame->codeBlock()->identifier(property); ASSERT(callFrame->r(function).jsValue().isObject()); - baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); + baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); ++vPC; NEXT_INSTRUCTION(); @@ -3926,12 +3900,12 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio CodeBlock* codeBlock = functionCallFrame->codeBlock(); if (codeBlock->usesArguments()) { ASSERT(codeBlock->codeType() == FunctionCode); - SymbolTable& symbolTable = codeBlock->symbolTable(); + SymbolTable& symbolTable = *codeBlock->symbolTable(); int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex(); - if (!functionCallFrame->r(argumentsIndex).arguments()) { + if (!functionCallFrame->r(argumentsIndex).jsValue()) { Arguments* arguments = new (callFrame) Arguments(functionCallFrame); functionCallFrame->setCalleeArguments(arguments); - functionCallFrame->r(RegisterFile::ArgumentsRegister) = arguments; + functionCallFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } return functionCallFrame->r(argumentsIndex).jsValue(); } @@ -3979,8 +3953,8 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp unsigned bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC()); lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1); - sourceID = callerCodeBlock->ownerNode()->sourceID(); - sourceURL = callerCodeBlock->ownerNode()->sourceURL(); + sourceID = callerCodeBlock->ownerExecutable()->sourceID(); + sourceURL = callerCodeBlock->ownerExecutable()->sourceURL(); function = callerFrame->callee(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h index 69f83cf..157e0c7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h @@ -42,19 +42,19 @@ namespace JSC { class CodeBlock; - class EvalNode; - class FunctionBodyNode; - class Instruction; + class EvalExecutable; + class FunctionExecutable; class InternalFunction; class JSFunction; class JSGlobalObject; - class ProgramNode; + class ProgramExecutable; class Register; class ScopeChainNode; class SamplingTool; struct CallFrameClosure; struct HandlerInfo; - + struct Instruction; + enum DebugHookID { WillExecuteProgram, DidExecuteProgram, @@ -95,9 +95,9 @@ namespace JSC { bool isOpcode(Opcode); - JSValue execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue* exception); - JSValue execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception); - JSValue execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception); + JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue* exception); + JSValue execute(FunctionExecutable*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception); + JSValue execute(EvalExecutable* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception); JSValue retrieveArguments(CallFrame*, JSFunction*) const; JSValue retrieveCaller(CallFrame*, InternalFunction*) const; @@ -115,11 +115,11 @@ namespace JSC { private: enum ExecutionFlag { Normal, InitializeAndReturn }; - CallFrameClosure prepareForRepeatCall(FunctionBodyNode*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*, JSValue* exception); + CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*, JSValue* exception); void endRepeatCall(CallFrameClosure&); JSValue execute(CallFrameClosure&, JSValue* exception); - JSValue execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception); + JSValue execute(EvalExecutable*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception); #if USE(INTERPRETER) NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h index 6d01eb7..ea1f849 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -51,24 +51,9 @@ namespace JSC { public: Register(); Register(JSValue); - Register(Arguments*); JSValue jsValue() const; - - bool marked() const; - void mark(); - int32_t i() const; - void* v() const; - - private: - friend class ExecState; - friend class Interpreter; - - // Only CallFrame, Interpreter, and JITStubs should use these functions. - - Register(intptr_t); - Register(JSActivation*); Register(CallFrame*); Register(CodeBlock*); @@ -77,6 +62,7 @@ namespace JSC { Register(ScopeChainNode*); Register(Instruction*); + int32_t i() const; JSActivation* activation() const; Arguments* arguments() const; CallFrame* callFrame() const; @@ -86,13 +72,19 @@ namespace JSC { ScopeChainNode* scopeChain() const; Instruction* vPC() const; + static Register withInt(int32_t i) + { + return Register(i); + } + + private: + Register(int32_t); + union { - intptr_t i; - void* v; + int32_t i; EncodedJSValue value; JSActivation* activation; - Arguments* arguments; CallFrame* callFrame; CodeBlock* codeBlock; JSObject* object; @@ -118,24 +110,9 @@ namespace JSC { { return JSValue::decode(u.value); } - - ALWAYS_INLINE bool Register::marked() const - { - return jsValue().marked(); - } - ALWAYS_INLINE void Register::mark() - { - jsValue().mark(); - } - // Interpreter functions - ALWAYS_INLINE Register::Register(Arguments* arguments) - { - u.arguments = arguments; - } - ALWAYS_INLINE Register::Register(JSActivation* activation) { u.activation = activation; @@ -171,35 +148,21 @@ namespace JSC { u.propertyNameIterator = propertyNameIterator; } - ALWAYS_INLINE Register::Register(intptr_t i) + ALWAYS_INLINE Register::Register(int32_t i) { - // See comment on 'i()' below. - ASSERT(i == static_cast<int32_t>(i)); u.i = i; } - // Read 'i' as a 32-bit integer; we only use it to hold 32-bit values, - // and we only write 32-bits when writing the arg count from JIT code. ALWAYS_INLINE int32_t Register::i() const { - return static_cast<int32_t>(u.i); + return u.i; } - ALWAYS_INLINE void* Register::v() const - { - return u.v; - } - ALWAYS_INLINE JSActivation* Register::activation() const { return u.activation; } - ALWAYS_INLINE Arguments* Register::arguments() const - { - return u.arguments; - } - ALWAYS_INLINE CallFrame* Register::callFrame() const { return u.callFrame; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h index 14e189e..0eeff0e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -136,8 +136,8 @@ namespace JSC { Register* lastGlobal() const { return m_start - m_numGlobals; } - void markGlobals(Heap* heap) { heap->markConservatively(lastGlobal(), m_start); } - void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); } + void markGlobals(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, lastGlobal(), m_start); } + void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, m_start, m_end); } private: void releaseExcessCapacity(); @@ -204,7 +204,15 @@ namespace JSC { CRASH(); } m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + committedSize); - #else // Neither MMAP nor VIRTUALALLOC - use fastMalloc instead + #else + /* + * If neither MMAP nor VIRTUALALLOC are available - use fastMalloc instead. + * + * Please note that this is the fallback case, which is non-optimal. + * If any possible, the platform should provide for a better memory + * allocation mechanism that allows for "lazy commit" or dynamic + * pre-allocation, similar to mmap or VirtualAlloc, to avoid waste of memory. + */ m_buffer = static_cast<Register*>(fastMalloc(bufferLength)); #endif m_start = m_buffer + maxGlobals; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h index 4ed47e3..12e2a32 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h @@ -38,6 +38,10 @@ #include <sys/mman.h> #endif +#if PLATFORM(SYMBIAN) +#include <e32std.h> +#endif + #define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize) #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4) @@ -176,30 +180,40 @@ public: static void cacheFlush(void*, size_t) { } -#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) +#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) static void cacheFlush(void* code, size_t size) { sys_dcache_flush(code, size); sys_icache_invalidate(code, size); } -#elif PLATFORM(ARM) +#elif PLATFORM(SYMBIAN) + static void cacheFlush(void* code, size_t size) + { + User::IMB_Range(code, static_cast<char*>(code) + size); + } +#elif PLATFORM(ARM) && COMPILER(GCC) && (GCC_VERSION >= 30406) && !defined(DISABLE_BUILTIN_CLEAR_CACHE) static void cacheFlush(void* code, size_t size) { - #if COMPILER(GCC) && (GCC_VERSION >= 30406) __clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(code) + size); - #else - const int syscall = 0xf0002; - __asm __volatile ( - "mov r0, %0\n" - "mov r1, %1\n" - "mov r7, %2\n" - "mov r2, #0x0\n" - "swi 0x00000000\n" - : - : "r" (code), "r" (reinterpret_cast<char*>(code) + size), "r" (syscall) - : "r0", "r1", "r7"); - #endif // COMPILER(GCC) && (GCC_VERSION >= 30406) } +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) + static void cacheFlush(void* code, size_t size) + { + asm volatile ( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "mov r7, #0xf0000\n" + "add r7, r7, #0x2\n" + "mov r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (code), "r" (reinterpret_cast<char*>(code) + size) + : "r0", "r1"); + } +#else + #error "The cacheFlush support is missing on this platform." #endif private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp index 4bd5a2c..13a8626 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp @@ -44,7 +44,10 @@ void ExecutableAllocator::intializePageSize() ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) { - ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0)), n }; + void* allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); + if (allocation == MAP_FAILED) + CRASH(); + ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; return alloc; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp index a9ba7d0..e6ac855 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp @@ -42,7 +42,10 @@ void ExecutableAllocator::intializePageSize() ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) { - ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)), n}; + void* allocation = VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!allocation) + CRASH(); + ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocation), n}; return alloc; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp index a0e462b..bf3a418 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp @@ -37,6 +37,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse #include "CodeBlock.h" #include "Interpreter.h" #include "JITInlineMethods.h" +#include "JITStubs.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" @@ -79,51 +80,67 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock) , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfStructureStubInfos() : 0) , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0) , m_bytecodeIndex((unsigned)-1) +#if USE(JSVALUE32_64) + , m_jumpTargetIndex(0) + , m_mappedBytecodeIndex((unsigned)-1) + , m_mappedVirtualRegisterIndex((unsigned)-1) + , m_mappedTag((RegisterID)-1) + , m_mappedPayload((RegisterID)-1) +#else , m_lastResultBytecodeRegister(std::numeric_limits<int>::max()) , m_jumpTargetsPosition(0) +#endif { } -void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type) +#if USE(JSVALUE32_64) +void JIT::emitTimeoutCheck() { - unsigned dst = currentInstruction[1].u.operand; - unsigned src1 = currentInstruction[2].u.operand; - unsigned src2 = currentInstruction[3].u.operand; - - emitGetVirtualRegisters(src1, regT0, src2, regT1); - - // Jump to a slow case if either operand is a number, or if both are JSCell*s. - move(regT0, regT2); - orPtr(regT1, regT2); - addSlowCase(emitJumpIfJSCell(regT2)); - addSlowCase(emitJumpIfImmediateNumber(regT2)); - - if (type == OpStrictEq) - set32(Equal, regT1, regT0, regT0); - else - set32(NotEqual, regT1, regT0, regT0); - emitTagAsBoolImmediate(regT0); - - emitPutVirtualRegister(dst); + Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister); + JITStubCall stubCall(this, cti_timeout_check); + stubCall.addArgument(regT1, regT0); // save last result registers. + stubCall.call(timeoutCheckRegister); + stubCall.getArgument(0, regT1, regT0); // reload last result registers. + skipTimeout.link(this); } - +#else void JIT::emitTimeoutCheck() { Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister); - JITStubCall(this, JITStubs::cti_timeout_check).call(timeoutCheckRegister); + JITStubCall(this, cti_timeout_check).call(timeoutCheckRegister); skipTimeout.link(this); killLastResultRegister(); } - +#endif #define NEXT_OPCODE(name) \ m_bytecodeIndex += OPCODE_LENGTH(name); \ break; +#if USE(JSVALUE32_64) #define DEFINE_BINARY_OP(name) \ case name: { \ - JITStubCall stubCall(this, JITStubs::cti_##name); \ + JITStubCall stubCall(this, cti_##name); \ + stubCall.addArgument(currentInstruction[2].u.operand); \ + stubCall.addArgument(currentInstruction[3].u.operand); \ + stubCall.call(currentInstruction[1].u.operand); \ + NEXT_OPCODE(name); \ + } + +#define DEFINE_UNARY_OP(name) \ + case name: { \ + JITStubCall stubCall(this, cti_##name); \ + stubCall.addArgument(currentInstruction[2].u.operand); \ + stubCall.call(currentInstruction[1].u.operand); \ + NEXT_OPCODE(name); \ + } + +#else // USE(JSVALUE32_64) + +#define DEFINE_BINARY_OP(name) \ + case name: { \ + JITStubCall stubCall(this, cti_##name); \ stubCall.addArgument(currentInstruction[2].u.operand, regT2); \ stubCall.addArgument(currentInstruction[3].u.operand, regT2); \ stubCall.call(currentInstruction[1].u.operand); \ @@ -132,11 +149,12 @@ void JIT::emitTimeoutCheck() #define DEFINE_UNARY_OP(name) \ case name: { \ - JITStubCall stubCall(this, JITStubs::cti_##name); \ + JITStubCall stubCall(this, cti_##name); \ stubCall.addArgument(currentInstruction[2].u.operand, regT2); \ stubCall.call(currentInstruction[1].u.operand); \ NEXT_OPCODE(name); \ } +#endif // USE(JSVALUE32_64) #define DEFINE_OP(name) \ case name: { \ @@ -168,14 +186,18 @@ void JIT::privateCompileMainPass() sampleInstruction(currentInstruction); #endif +#if !USE(JSVALUE32_64) if (m_labels[m_bytecodeIndex].isUsed()) killLastResultRegister(); - +#endif + m_labels[m_bytecodeIndex] = label(); switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) { DEFINE_BINARY_OP(op_del_by_val) +#if !USE(JSVALUE32_64) DEFINE_BINARY_OP(op_div) +#endif DEFINE_BINARY_OP(op_in) DEFINE_BINARY_OP(op_less) DEFINE_BINARY_OP(op_lesseq) @@ -187,7 +209,9 @@ void JIT::privateCompileMainPass() DEFINE_UNARY_OP(op_is_object) DEFINE_UNARY_OP(op_is_string) DEFINE_UNARY_OP(op_is_undefined) +#if !USE(JSVALUE32_64) DEFINE_UNARY_OP(op_negate) +#endif DEFINE_UNARY_OP(op_typeof) DEFINE_OP(op_add) @@ -206,6 +230,9 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_create_arguments) DEFINE_OP(op_debug) DEFINE_OP(op_del_by_id) +#if USE(JSVALUE32_64) + DEFINE_OP(op_div) +#endif DEFINE_OP(op_end) DEFINE_OP(op_enter) DEFINE_OP(op_enter_with_activation) @@ -236,6 +263,9 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_mod) DEFINE_OP(op_mov) DEFINE_OP(op_mul) +#if USE(JSVALUE32_64) + DEFINE_OP(op_negate) +#endif DEFINE_OP(op_neq) DEFINE_OP(op_neq_null) DEFINE_OP(op_new_array) @@ -265,7 +295,6 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_put_setter) DEFINE_OP(op_resolve) DEFINE_OP(op_resolve_base) - DEFINE_OP(op_resolve_func) DEFINE_OP(op_resolve_global) DEFINE_OP(op_resolve_skip) DEFINE_OP(op_resolve_with_base) @@ -322,11 +351,15 @@ void JIT::privateCompileSlowCases() Instruction* instructionsBegin = m_codeBlock->instructions().begin(); m_propertyAccessInstructionIndex = 0; +#if USE(JSVALUE32_64) + m_globalResolveInfoIndex = 0; +#endif m_callLinkInfoIndex = 0; for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) { - // FIXME: enable peephole optimizations for slow cases when applicable +#if !USE(JSVALUE32_64) killLastResultRegister(); +#endif m_bytecodeIndex = iter->to; #ifndef NDEBUG @@ -346,6 +379,9 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_construct) DEFINE_SLOWCASE_OP(op_construct_verify) DEFINE_SLOWCASE_OP(op_convert_this) +#if USE(JSVALUE32_64) + DEFINE_SLOWCASE_OP(op_div) +#endif DEFINE_SLOWCASE_OP(op_eq) DEFINE_SLOWCASE_OP(op_get_by_id) DEFINE_SLOWCASE_OP(op_get_by_val) @@ -358,9 +394,12 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_loop_if_lesseq) DEFINE_SLOWCASE_OP(op_loop_if_true) DEFINE_SLOWCASE_OP(op_lshift) + DEFINE_SLOWCASE_OP(op_method_check) DEFINE_SLOWCASE_OP(op_mod) DEFINE_SLOWCASE_OP(op_mul) - DEFINE_SLOWCASE_OP(op_method_check) +#if USE(JSVALUE32_64) + DEFINE_SLOWCASE_OP(op_negate) +#endif DEFINE_SLOWCASE_OP(op_neq) DEFINE_SLOWCASE_OP(op_not) DEFINE_SLOWCASE_OP(op_nstricteq) @@ -370,6 +409,9 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_pre_inc) DEFINE_SLOWCASE_OP(op_put_by_id) DEFINE_SLOWCASE_OP(op_put_by_val) +#if USE(JSVALUE32_64) + DEFINE_SLOWCASE_OP(op_resolve_global) +#endif DEFINE_SLOWCASE_OP(op_rshift) DEFINE_SLOWCASE_OP(op_stricteq) DEFINE_SLOWCASE_OP(op_sub) @@ -396,7 +438,7 @@ void JIT::privateCompileSlowCases() #endif } -void JIT::privateCompile() +JITCode JIT::privateCompile() { sampleCodeBlock(m_codeBlock); #if ENABLE(OPCODE_SAMPLING) @@ -427,7 +469,7 @@ void JIT::privateCompile() if (m_codeBlock->codeType() == FunctionCode) { slowRegisterFileCheck.link(this); m_bytecodeIndex = 0; - JITStubCall(this, JITStubs::cti_register_file_check).call(); + JITStubCall(this, cti_register_file_check).call(); #ifndef NDEBUG m_bytecodeIndex = (unsigned)-1; // Reset this, in order to guard its use with ASSERTs. #endif @@ -510,389 +552,10 @@ void JIT::privateCompile() info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation; } - m_codeBlock->setJITCode(patchBuffer.finalizeCode()); -} - -void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiArrayLengthTrampoline, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) -{ -#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - // (1) The first function provides fast property access for array length - Label arrayLengthBegin = align(); - - // Check eax is an array - Jump array_failureCases1 = emitJumpIfNotJSCell(regT0); - Jump array_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)); - - // Checks out okay! - get the length from the storage - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - load32(Address(regT0, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT0); - - Jump array_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt)); - - // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here. - emitFastArithIntToImmNoCheck(regT0, regT0); - - ret(); - - // (2) The second function provides fast property access for string length - Label stringLengthBegin = align(); - - // Check eax is a string - Jump string_failureCases1 = emitJumpIfNotJSCell(regT0); - Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)); - - // Checks out okay! - get the length from the Ustring. - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT0); - load32(Address(regT0, OBJECT_OFFSETOF(UString::Rep, len)), regT0); - - Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt)); - - // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here. - emitFastArithIntToImmNoCheck(regT0, regT0); - - ret(); -#endif - - // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct. - COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit); - - Label virtualCallPreLinkBegin = align(); - - // Load the callee CodeBlock* into eax - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); - loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0); - Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0); - preserveReturnAddressAfterCall(regT3); - restoreArgumentReference(); - Call callJSFunction1 = call(); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - hasCodeBlock1.link(this); - - Jump isNativeFunc1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode)); - - // Check argCount matches callee arity. - Jump arityCheckOkay1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1); - preserveReturnAddressAfterCall(regT3); - emitPutJITStubArg(regT3, 2); - emitPutJITStubArg(regT0, 4); - restoreArgumentReference(); - Call callArityCheck1 = call(); - move(regT1, callFrameRegister); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - arityCheckOkay1.link(this); - isNativeFunc1.link(this); - - compileOpCallInitializeCallFrame(); - - preserveReturnAddressAfterCall(regT3); - emitPutJITStubArg(regT3, 2); - restoreArgumentReference(); - Call callDontLazyLinkCall = call(); - emitGetJITStubArg(1, regT2); - restoreReturnAddressBeforeReturn(regT3); - - jump(regT0); - - Label virtualCallLinkBegin = align(); - - // Load the callee CodeBlock* into eax - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); - loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0); - Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0); - preserveReturnAddressAfterCall(regT3); - restoreArgumentReference(); - Call callJSFunction2 = call(); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - hasCodeBlock2.link(this); - - Jump isNativeFunc2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode)); - - // Check argCount matches callee arity. - Jump arityCheckOkay2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1); - preserveReturnAddressAfterCall(regT3); - emitPutJITStubArg(regT3, 2); - emitPutJITStubArg(regT0, 4); - restoreArgumentReference(); - Call callArityCheck2 = call(); - move(regT1, callFrameRegister); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - arityCheckOkay2.link(this); - isNativeFunc2.link(this); - - compileOpCallInitializeCallFrame(); - - preserveReturnAddressAfterCall(regT3); - emitPutJITStubArg(regT3, 2); - restoreArgumentReference(); - Call callLazyLinkCall = call(); - restoreReturnAddressBeforeReturn(regT3); - - jump(regT0); - - Label virtualCallBegin = align(); - - // Load the callee CodeBlock* into eax - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); - loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0); - Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0); - preserveReturnAddressAfterCall(regT3); - restoreArgumentReference(); - Call callJSFunction3 = call(); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); // reload the function body nody, so we can reload the code pointer. - hasCodeBlock3.link(this); - - Jump isNativeFunc3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode)); - - // Check argCount matches callee arity. - Jump arityCheckOkay3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1); - preserveReturnAddressAfterCall(regT3); - emitPutJITStubArg(regT3, 2); - emitPutJITStubArg(regT0, 4); - restoreArgumentReference(); - Call callArityCheck3 = call(); - move(regT1, callFrameRegister); - emitGetJITStubArg(1, regT2); - emitGetJITStubArg(3, regT1); - restoreReturnAddressBeforeReturn(regT3); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); // reload the function body nody, so we can reload the code pointer. - arityCheckOkay3.link(this); - isNativeFunc3.link(this); - - // load ctiCode from the new codeBlock. - loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_jitCode)), regT0); - - compileOpCallInitializeCallFrame(); - jump(regT0); - - - Label nativeCallThunk = align(); - preserveReturnAddressAfterCall(regT0); - emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address - - // Load caller frame's scope chain into this callframe so that whatever we call can - // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT1); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1); - emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); - - -#if PLATFORM(X86_64) - emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86::ecx); - - // Allocate stack space for our arglist - subPtr(Imm32(sizeof(ArgList)), stackPointerRegister); - COMPILE_ASSERT((sizeof(ArgList) & 0xf) == 0, ArgList_should_by_16byte_aligned); - - // Set up arguments - subPtr(Imm32(1), X86::ecx); // Don't include 'this' in argcount - - // Push argcount - storePtr(X86::ecx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount))); - - // Calculate the start of the callframe header, and store in edx - addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), callFrameRegister, X86::edx); - - // Calculate start of arguments as callframe header - sizeof(Register) * argcount (ecx) - mul32(Imm32(sizeof(Register)), X86::ecx, X86::ecx); - subPtr(X86::ecx, X86::edx); - - // push pointer to arguments - storePtr(X86::edx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args))); - - // ArgList is passed by reference so is stackPointerRegister - move(stackPointerRegister, X86::ecx); - - // edx currently points to the first argument, edx-sizeof(Register) points to 'this' - loadPtr(Address(X86::edx, -(int32_t)sizeof(Register)), X86::edx); - - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::esi); - - move(callFrameRegister, X86::edi); - - call(Address(X86::esi, OBJECT_OFFSETOF(JSFunction, m_data))); - - addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); -#elif PLATFORM(X86) - emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); - - /* We have two structs that we use to describe the stackframe we set up for our - * call to native code. NativeCallFrameStructure describes the how we set up the stack - * in advance of the call. NativeFunctionCalleeSignature describes the callframe - * as the native code expects it. We do this as we are using the fastcall calling - * convention which results in the callee popping its arguments off the stack, but - * not the rest of the callframe so we need a nice way to ensure we increment the - * stack pointer by the right amount after the call. - */ -#if COMPILER(MSVC) || PLATFORM(LINUX) - struct NativeCallFrameStructure { - // CallFrame* callFrame; // passed in EDX - JSObject* callee; - JSValue thisValue; - ArgList* argPointer; - ArgList args; - JSValue result; - }; - struct NativeFunctionCalleeSignature { - JSObject* callee; - JSValue thisValue; - ArgList* argPointer; - }; -#else - struct NativeCallFrameStructure { - // CallFrame* callFrame; // passed in ECX - // JSObject* callee; // passed in EDX - JSValue thisValue; - ArgList* argPointer; - ArgList args; - }; - struct NativeFunctionCalleeSignature { - JSValue thisValue; - ArgList* argPointer; - }; -#endif - const int NativeCallFrameSize = (sizeof(NativeCallFrameStructure) + 15) & ~15; - // Allocate system stack frame - subPtr(Imm32(NativeCallFrameSize), stackPointerRegister); - - // Set up arguments - subPtr(Imm32(1), regT0); // Don't include 'this' in argcount - - // push argcount - storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_argCount))); - - // Calculate the start of the callframe header, and store in regT1 - addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int)sizeof(Register)), callFrameRegister, regT1); - - // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0) - mul32(Imm32(sizeof(Register)), regT0, regT0); - subPtr(regT0, regT1); - storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_args))); - - // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) - addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, args)), stackPointerRegister, regT0); - storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, argPointer))); - - // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this' - loadPtr(Address(regT1, -(int)sizeof(Register)), regT1); - storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue))); - -#if COMPILER(MSVC) || PLATFORM(LINUX) - // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) - addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86::ecx); - - // Plant callee - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::eax); - storePtr(X86::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee))); - - // Plant callframe - move(callFrameRegister, X86::edx); - - call(Address(X86::eax, OBJECT_OFFSETOF(JSFunction, m_data))); - - // JSValue is a non-POD type - loadPtr(Address(X86::eax), X86::eax); -#else - // Plant callee - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::edx); - - // Plant callframe - move(callFrameRegister, X86::ecx); - call(Address(X86::edx, OBJECT_OFFSETOF(JSFunction, m_data))); -#endif - - // We've put a few temporaries on the stack in addition to the actual arguments - // so pull them off now - addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); - -#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) -#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." -#else - breakpoint(); -#endif - - // Check for an exception - loadPtr(&(globalData->exception), regT2); - Jump exceptionHandler = branchTestPtr(NonZero, regT2); - - // Grab the return address. - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); - - // Restore our caller's "r". - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); - - // Return. - restoreReturnAddressBeforeReturn(regT1); - ret(); - - // Handle an exception - exceptionHandler.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); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); - poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); - restoreReturnAddressBeforeReturn(regT2); - ret(); - - -#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - Call array_failureCases1Call = makeTailRecursiveCall(array_failureCases1); - Call array_failureCases2Call = makeTailRecursiveCall(array_failureCases2); - Call array_failureCases3Call = makeTailRecursiveCall(array_failureCases3); - Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1); - Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2); - Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3); -#endif - - // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. - LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size())); - -#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - patchBuffer.link(array_failureCases1Call, FunctionPtr(JITStubs::cti_op_get_by_id_array_fail)); - patchBuffer.link(array_failureCases2Call, FunctionPtr(JITStubs::cti_op_get_by_id_array_fail)); - patchBuffer.link(array_failureCases3Call, FunctionPtr(JITStubs::cti_op_get_by_id_array_fail)); - patchBuffer.link(string_failureCases1Call, FunctionPtr(JITStubs::cti_op_get_by_id_string_fail)); - patchBuffer.link(string_failureCases2Call, FunctionPtr(JITStubs::cti_op_get_by_id_string_fail)); - patchBuffer.link(string_failureCases3Call, FunctionPtr(JITStubs::cti_op_get_by_id_string_fail)); -#endif - patchBuffer.link(callArityCheck1, FunctionPtr(JITStubs::cti_op_call_arityCheck)); - patchBuffer.link(callArityCheck2, FunctionPtr(JITStubs::cti_op_call_arityCheck)); - patchBuffer.link(callArityCheck3, FunctionPtr(JITStubs::cti_op_call_arityCheck)); - patchBuffer.link(callJSFunction1, FunctionPtr(JITStubs::cti_op_call_JSFunction)); - patchBuffer.link(callJSFunction2, FunctionPtr(JITStubs::cti_op_call_JSFunction)); - patchBuffer.link(callJSFunction3, FunctionPtr(JITStubs::cti_op_call_JSFunction)); - patchBuffer.link(callDontLazyLinkCall, FunctionPtr(JITStubs::cti_vm_dontLazyLinkCall)); - patchBuffer.link(callLazyLinkCall, FunctionPtr(JITStubs::cti_vm_lazyLinkCall)); - - CodeRef finalCode = patchBuffer.finalizeCode(); - *executablePool = finalCode.m_executablePool; - - *ctiVirtualCallPreLink = trampolineAt(finalCode, virtualCallPreLinkBegin); - *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); - *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); - *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); -#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - *ctiArrayLengthTrampoline = trampolineAt(finalCode, arrayLengthBegin); - *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); -#else - UNUSED_PARAM(ctiArrayLengthTrampoline); - UNUSED_PARAM(ctiStringLengthTrampoline); -#endif + return patchBuffer.finalizeCode(); } +#if !USE(JSVALUE32_64) void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst) { loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject, d)), dst); @@ -906,24 +569,29 @@ void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObjec loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), variableObject); storePtr(src, Address(variableObject, index * sizeof(Register))); } +#endif +#if ENABLE(JIT_OPTIMIZE_CALL) void JIT::unlinkCall(CallLinkInfo* callLinkInfo) { // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive // match). Reset the check so it no longer matches. - RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock); + RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock.get()); +#if USE(JSVALUE32_64) + repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0); +#else repatchBuffer.repatch(callLinkInfo->hotPathBegin, JSValue::encode(JSValue())); +#endif } void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData) { - ASSERT(calleeCodeBlock); RepatchBuffer repatchBuffer(callerCodeBlock); // Currently we only link calls with the exact number of arguments. // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant - if (callerArgCount == calleeCodeBlock->m_numParameters || calleeCodeBlock->codeType() == NativeCode) { + if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) { ASSERT(!callLinkInfo->isLinked()); if (calleeCodeBlock) @@ -936,6 +604,7 @@ void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* ca // patch the call so we do not continue to try to link. repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs.ctiVirtualCall()); } +#endif // ENABLE(JIT_OPTIMIZE_CALL) } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h index ceffe59..5c58e9d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h @@ -28,11 +28,6 @@ #include <wtf/Platform.h> -// 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 -// NULL can cause compiler problems, especially in cases of multiple inheritance. -#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000) - #if ENABLE(JIT) // We've run into some problems where changing the size of the class JIT leads to @@ -64,14 +59,14 @@ namespace JSC { class Register; class RegisterFile; class ScopeChainNode; - class SimpleJumpTable; - class StringJumpTable; class StructureChain; struct CallLinkInfo; struct Instruction; struct OperandTypes; struct PolymorphicAccessStructureList; + struct SimpleJumpTable; + struct StringJumpTable; struct StructureStubInfo; struct CallRecord { @@ -177,7 +172,6 @@ namespace JSC { class JIT : private MacroAssembler { friend class JITStubCall; - friend class CallEvalJITStub; using MacroAssembler::Jump; using MacroAssembler::JumpList; @@ -197,57 +191,82 @@ namespace JSC { // MacroAssembler will need to plant register swaps if it is not - // however the code will still function correctly. #if PLATFORM(X86_64) - static const RegisterID returnValueRegister = X86::eax; - static const RegisterID cachedResultRegister = X86::eax; - static const RegisterID firstArgumentRegister = X86::edi; - - static const RegisterID timeoutCheckRegister = X86::r12; - static const RegisterID callFrameRegister = X86::r13; - static const RegisterID tagTypeNumberRegister = X86::r14; - static const RegisterID tagMaskRegister = X86::r15; - - static const RegisterID regT0 = X86::eax; - static const RegisterID regT1 = X86::edx; - static const RegisterID regT2 = X86::ecx; - static const RegisterID regT3 = X86::ebx; - - static const FPRegisterID fpRegT0 = X86::xmm0; - static const FPRegisterID fpRegT1 = X86::xmm1; - static const FPRegisterID fpRegT2 = X86::xmm2; + static const RegisterID returnValueRegister = X86Registers::eax; + static const RegisterID cachedResultRegister = X86Registers::eax; + static const RegisterID firstArgumentRegister = X86Registers::edi; + + static const RegisterID timeoutCheckRegister = X86Registers::r12; + static const RegisterID callFrameRegister = X86Registers::r13; + static const RegisterID tagTypeNumberRegister = X86Registers::r14; + static const RegisterID tagMaskRegister = X86Registers::r15; + + static const RegisterID regT0 = X86Registers::eax; + static const RegisterID regT1 = X86Registers::edx; + static const RegisterID regT2 = X86Registers::ecx; + static const RegisterID regT3 = X86Registers::ebx; + + static const FPRegisterID fpRegT0 = X86Registers::xmm0; + static const FPRegisterID fpRegT1 = X86Registers::xmm1; + static const FPRegisterID fpRegT2 = X86Registers::xmm2; #elif PLATFORM(X86) - static const RegisterID returnValueRegister = X86::eax; - static const RegisterID cachedResultRegister = X86::eax; + static const RegisterID returnValueRegister = X86Registers::eax; + static const RegisterID cachedResultRegister = X86Registers::eax; // On x86 we always use fastcall conventions = but on // OS X if might make more sense to just use regparm. - static const RegisterID firstArgumentRegister = X86::ecx; - - static const RegisterID timeoutCheckRegister = X86::esi; - static const RegisterID callFrameRegister = X86::edi; - - static const RegisterID regT0 = X86::eax; - static const RegisterID regT1 = X86::edx; - static const RegisterID regT2 = X86::ecx; - static const RegisterID regT3 = X86::ebx; - - static const FPRegisterID fpRegT0 = X86::xmm0; - static const FPRegisterID fpRegT1 = X86::xmm1; - static const FPRegisterID fpRegT2 = X86::xmm2; -#elif PLATFORM_ARM_ARCH(7) - static const RegisterID returnValueRegister = ARM::r0; - static const RegisterID cachedResultRegister = ARM::r0; - static const RegisterID firstArgumentRegister = ARM::r0; - - static const RegisterID regT0 = ARM::r0; - static const RegisterID regT1 = ARM::r1; - static const RegisterID regT2 = ARM::r2; - static const RegisterID regT3 = ARM::r4; - - static const RegisterID callFrameRegister = ARM::r5; - static const RegisterID timeoutCheckRegister = ARM::r6; - - static const FPRegisterID fpRegT0 = ARM::d0; - static const FPRegisterID fpRegT1 = ARM::d1; - static const FPRegisterID fpRegT2 = ARM::d2; + static const RegisterID firstArgumentRegister = X86Registers::ecx; + + static const RegisterID timeoutCheckRegister = X86Registers::esi; + static const RegisterID callFrameRegister = X86Registers::edi; + + static const RegisterID regT0 = X86Registers::eax; + static const RegisterID regT1 = X86Registers::edx; + static const RegisterID regT2 = X86Registers::ecx; + static const RegisterID regT3 = X86Registers::ebx; + + static const FPRegisterID fpRegT0 = X86Registers::xmm0; + static const FPRegisterID fpRegT1 = X86Registers::xmm1; + static const FPRegisterID fpRegT2 = X86Registers::xmm2; +#elif PLATFORM(ARM_THUMB2) + static const RegisterID returnValueRegister = ARMRegisters::r0; + static const RegisterID cachedResultRegister = ARMRegisters::r0; + static const RegisterID firstArgumentRegister = ARMRegisters::r0; + + static const RegisterID regT0 = ARMRegisters::r0; + static const RegisterID regT1 = ARMRegisters::r1; + static const RegisterID regT2 = ARMRegisters::r2; + static const RegisterID regT3 = ARMRegisters::r4; + + static const RegisterID callFrameRegister = ARMRegisters::r5; + static const RegisterID timeoutCheckRegister = ARMRegisters::r6; + + static const FPRegisterID fpRegT0 = ARMRegisters::d0; + static const FPRegisterID fpRegT1 = ARMRegisters::d1; + static const FPRegisterID fpRegT2 = ARMRegisters::d2; +#elif PLATFORM(ARM_TRADITIONAL) + static const RegisterID returnValueRegister = ARMRegisters::r0; + static const RegisterID cachedResultRegister = ARMRegisters::r0; + static const RegisterID firstArgumentRegister = ARMRegisters::r0; + + 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; + static const RegisterID regT2 = ARMRegisters::r2; + // Callee preserved + static const RegisterID regT3 = ARMRegisters::r7; + + static const RegisterID regS0 = ARMRegisters::S0; + // Callee preserved + static const RegisterID regS1 = ARMRegisters::S1; + + static const RegisterID regStackPtr = ARMRegisters::sp; + static const RegisterID regLink = ARMRegisters::lr; + + static const FPRegisterID fpRegT0 = ARMRegisters::d0; + static const FPRegisterID fpRegT1 = ARMRegisters::d1; + static const FPRegisterID fpRegT2 = ARMRegisters::d2; #else #error "JIT not supported on this platform." #endif @@ -257,86 +276,10 @@ namespace JSC { // will compress the displacement, and we may not be able to fit a patched offset. static const int patchGetByIdDefaultOffset = 256; -#if PLATFORM(X86_64) - // 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 patchLengthPutByIdExternalLoad = 4; - static const int patchOffsetPutByIdPropertyMapOffset = 31; - // 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 patchLengthGetByIdExternalLoad = 4; - static const int patchOffsetGetByIdPropertyMapOffset = 31; - static const int patchOffsetGetByIdPutResult = 31; -#if ENABLE(OPCODE_SAMPLING) - static const int patchOffsetGetByIdSlowCaseCall = 66; -#else - static const int patchOffsetGetByIdSlowCaseCall = 44; -#endif - static const int patchOffsetOpCallCompareToJump = 9; - - static const int patchOffsetMethodCheckProtoObj = 20; - static const int patchOffsetMethodCheckProtoStruct = 30; - static const int patchOffsetMethodCheckPutFunction = 50; -#elif PLATFORM(X86) - // These architecture specific value are used to enable patching - see comment on op_put_by_id. - static const int patchOffsetPutByIdStructure = 7; - static const int patchOffsetPutByIdExternalLoad = 13; - static const int patchLengthPutByIdExternalLoad = 3; - static const int patchOffsetPutByIdPropertyMapOffset = 22; - // These architecture specific value are used to enable patching - see comment on op_get_by_id. - static const int patchOffsetGetByIdStructure = 7; - static const int patchOffsetGetByIdBranchToSlowCase = 13; - static const int patchOffsetGetByIdExternalLoad = 13; - static const int patchLengthGetByIdExternalLoad = 3; - static const int patchOffsetGetByIdPropertyMapOffset = 22; - static const int patchOffsetGetByIdPutResult = 22; -#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 31; -#elif ENABLE(OPCODE_SAMPLING) - static const int patchOffsetGetByIdSlowCaseCall = 33; -#elif USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 21; -#else - static const int patchOffsetGetByIdSlowCaseCall = 23; -#endif - static const int patchOffsetOpCallCompareToJump = 6; - - static const int patchOffsetMethodCheckProtoObj = 11; - static const int patchOffsetMethodCheckProtoStruct = 18; - static const int patchOffsetMethodCheckPutFunction = 29; -#elif PLATFORM_ARM_ARCH(7) - // 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 patchLengthPutByIdExternalLoad = 12; - static const int patchOffsetPutByIdPropertyMapOffset = 40; - // 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 patchLengthGetByIdExternalLoad = 12; - static const int patchOffsetGetByIdPropertyMapOffset = 40; - static const int patchOffsetGetByIdPutResult = 44; -#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 patchOffsetMethodCheckProtoObj = 18; - static const int patchOffsetMethodCheckProtoStruct = 28; - static const int patchOffsetMethodCheckPutFunction = 46; -#endif - public: - static void compile(JSGlobalData* globalData, CodeBlock* codeBlock) + static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock) { - JIT jit(globalData, codeBlock); - jit.privateCompile(); + return JIT(globalData, codeBlock).privateCompile(); } static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress) @@ -373,15 +316,15 @@ namespace JSC { jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress); } - static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiArrayLengthTrampoline, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) + static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) { JIT jit(globalData); - jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiArrayLengthTrampoline, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk); + jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk); } static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); - static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*); + static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr); static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress) { @@ -409,7 +352,7 @@ namespace JSC { void privateCompileMainPass(); void privateCompileLinkPass(); void privateCompileSlowCases(); - void privateCompile(); + JITCode privateCompile(); void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, size_t cachedOffset); void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame); @@ -417,17 +360,14 @@ namespace JSC { void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress); - void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiArrayLengthTrampoline, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk); + void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk); void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress); void addSlowCase(Jump); + void addSlowCase(JumpList); void addJump(Jump, int); void emitJumpSlowToHot(Jump, int); -#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex); - void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex, bool isMethodCheck = false); -#endif void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex); void compileOpCallVarargs(Instruction* instruction); void compileOpCallInitializeCallFrame(); @@ -436,164 +376,428 @@ namespace JSC { void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID); void compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter); void compileOpConstructSetupArgs(Instruction*); + enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); +#if USE(JSVALUE32_64) + Address tagFor(unsigned index, RegisterID base = callFrameRegister); + Address payloadFor(unsigned index, RegisterID base = callFrameRegister); + Address addressFor(unsigned index, RegisterID base = callFrameRegister); + + bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant); + bool isOperandConstantImmediateDouble(unsigned src); + + void emitLoadTag(unsigned index, RegisterID tag); + void emitLoadPayload(unsigned index, RegisterID payload); + + void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload); + void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); + void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2); + void emitLoadDouble(unsigned index, FPRegisterID value); + void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); + + void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); + void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister); + void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false); + void emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32 = false); + void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false); + void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false); + void emitStoreDouble(unsigned index, FPRegisterID value); + + bool isLabeled(unsigned bytecodeIndex); + void map(unsigned bytecodeIndex, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload); + void unmap(RegisterID); + void unmap(); + bool isMapped(unsigned virtualRegisterIndex); + bool getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload); + bool getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag); + + void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex); + void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag); + void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, unsigned virtualRegisterIndex); + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + void compileGetByIdHotPath(); + void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); +#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 compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); + + // Arithmetic opcode helpers + void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); + void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); + void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true); + +#if PLATFORM(X86) + // These architecture specific value are used to enable patching - see comment on op_put_by_id. + static const int patchOffsetPutByIdStructure = 7; + static const int patchOffsetPutByIdExternalLoad = 13; + static const int patchLengthPutByIdExternalLoad = 3; + static const int patchOffsetPutByIdPropertyMapOffset1 = 22; + static const int patchOffsetPutByIdPropertyMapOffset2 = 28; + // These architecture specific value are used to enable patching - see comment on op_get_by_id. + static const int patchOffsetGetByIdStructure = 7; + static const int patchOffsetGetByIdBranchToSlowCase = 13; + static const int patchOffsetGetByIdExternalLoad = 13; + static const int patchLengthGetByIdExternalLoad = 3; + static const int patchOffsetGetByIdPropertyMapOffset1 = 22; + static const int patchOffsetGetByIdPropertyMapOffset2 = 28; + static const int patchOffsetGetByIdPutResult = 28; +#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST) + static const int patchOffsetGetByIdSlowCaseCall = 35; +#elif ENABLE(OPCODE_SAMPLING) + static const int patchOffsetGetByIdSlowCaseCall = 37; +#elif USE(JIT_STUB_ARGUMENT_VA_LIST) + static const int patchOffsetGetByIdSlowCaseCall = 25; +#else + static const int patchOffsetGetByIdSlowCaseCall = 27; +#endif + static const int patchOffsetOpCallCompareToJump = 6; + + static const int patchOffsetMethodCheckProtoObj = 11; + static const int patchOffsetMethodCheckProtoStruct = 18; + static const int patchOffsetMethodCheckPutFunction = 29; +#else +#error "JSVALUE32_64 not supported on this platform." +#endif + +#else // USE(JSVALUE32_64) + void emitGetVirtualRegister(int src, RegisterID dst); + void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2); + void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0); + + int32_t getConstantOperandImmediateInt(unsigned src); + + void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst); + void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index); + + void killLastResultRegister(); + + Jump emitJumpIfJSCell(RegisterID); + Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID); + void emitJumpSlowCaseIfJSCell(RegisterID); + Jump emitJumpIfNotJSCell(RegisterID); + void emitJumpSlowCaseIfNotJSCell(RegisterID); + void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg); +#if USE(JSVALUE64) + JIT::Jump emitJumpIfImmediateNumber(RegisterID); + JIT::Jump emitJumpIfNotImmediateNumber(RegisterID); +#else + JIT::Jump emitJumpIfImmediateNumber(RegisterID reg) + { + return emitJumpIfImmediateInteger(reg); + } + + JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg) + { + return emitJumpIfNotImmediateInteger(reg); + } +#endif + JIT::Jump emitJumpIfImmediateInteger(RegisterID); + JIT::Jump emitJumpIfNotImmediateInteger(RegisterID); + JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); + void emitJumpSlowCaseIfNotImmediateInteger(RegisterID); + void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); + +#if !USE(JSVALUE64) + void emitFastArithDeTagImmediate(RegisterID); + Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID); +#endif + void emitFastArithReTagImmediate(RegisterID src, RegisterID dest); + void emitFastArithImmToInt(RegisterID); + void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest); + + void emitTagAsBoolImmediate(RegisterID reg); + void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); + void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex); + void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); +#endif void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); - // Arithmetic Ops +#if PLATFORM(X86_64) + // 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 patchLengthPutByIdExternalLoad = 4; + static const int patchOffsetPutByIdPropertyMapOffset = 31; + // 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 patchLengthGetByIdExternalLoad = 4; + static const int patchOffsetGetByIdPropertyMapOffset = 31; + static const int patchOffsetGetByIdPutResult = 31; +#if ENABLE(OPCODE_SAMPLING) + static const int patchOffsetGetByIdSlowCaseCall = 63; +#else + static const int patchOffsetGetByIdSlowCaseCall = 41; +#endif + static const int patchOffsetOpCallCompareToJump = 9; - void emit_op_add(Instruction*); - void emit_op_sub(Instruction*); - void emit_op_mul(Instruction*); - void emit_op_mod(Instruction*); - void emit_op_bitand(Instruction*); - void emit_op_lshift(Instruction*); - void emit_op_rshift(Instruction*); - void emit_op_jnless(Instruction*); - void emit_op_jnlesseq(Instruction*); - void emit_op_pre_inc(Instruction*); - void emit_op_pre_dec(Instruction*); - void emit_op_post_inc(Instruction*); - void emit_op_post_dec(Instruction*); - void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&); + static const int patchOffsetMethodCheckProtoObj = 20; + static const int patchOffsetMethodCheckProtoStruct = 30; + static const int patchOffsetMethodCheckPutFunction = 50; +#elif PLATFORM(X86) + // These architecture specific value are used to enable patching - see comment on op_put_by_id. + static const int patchOffsetPutByIdStructure = 7; + static const int patchOffsetPutByIdExternalLoad = 13; + static const int patchLengthPutByIdExternalLoad = 3; + static const int patchOffsetPutByIdPropertyMapOffset = 22; + // These architecture specific value are used to enable patching - see comment on op_get_by_id. + static const int patchOffsetGetByIdStructure = 7; + static const int patchOffsetGetByIdBranchToSlowCase = 13; + static const int patchOffsetGetByIdExternalLoad = 13; + static const int patchLengthGetByIdExternalLoad = 3; + static const int patchOffsetGetByIdPropertyMapOffset = 22; + static const int patchOffsetGetByIdPutResult = 22; +#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST) + static const int patchOffsetGetByIdSlowCaseCall = 31; +#elif ENABLE(OPCODE_SAMPLING) + static const int patchOffsetGetByIdSlowCaseCall = 33; +#elif USE(JIT_STUB_ARGUMENT_VA_LIST) + static const int patchOffsetGetByIdSlowCaseCall = 21; +#else + static const int patchOffsetGetByIdSlowCaseCall = 23; +#endif + static const int patchOffsetOpCallCompareToJump = 6; - void emit_op_get_by_val(Instruction*); - void emit_op_put_by_val(Instruction*); - void emit_op_put_by_index(Instruction*); - void emit_op_put_getter(Instruction*); - void emit_op_put_setter(Instruction*); - void emit_op_del_by_id(Instruction*); + static const int patchOffsetMethodCheckProtoObj = 11; + static const int patchOffsetMethodCheckProtoStruct = 18; + static const int patchOffsetMethodCheckPutFunction = 29; +#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 patchLengthPutByIdExternalLoad = 12; + static const int patchOffsetPutByIdPropertyMapOffset = 40; + // 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 patchLengthGetByIdExternalLoad = 12; + static const int patchOffsetGetByIdPropertyMapOffset = 40; + static const int patchOffsetGetByIdPutResult = 44; +#if ENABLE(OPCODE_SAMPLING) + static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE +#else + static const int patchOffsetGetByIdSlowCaseCall = 28; +#endif + static const int patchOffsetOpCallCompareToJump = 10; - void emit_op_mov(Instruction*); - void emit_op_end(Instruction*); - void emit_op_jmp(Instruction*); - void emit_op_loop(Instruction*); - void emit_op_loop_if_less(Instruction*); - void emit_op_loop_if_lesseq(Instruction*); - void emit_op_new_object(Instruction*); - void emit_op_put_by_id(Instruction*); - void emit_op_get_by_id(Instruction*); - void emit_op_instanceof(Instruction*); - void emit_op_new_func(Instruction*); + static const int patchOffsetMethodCheckProtoObj = 18; + static const int patchOffsetMethodCheckProtoStruct = 28; + static const int patchOffsetMethodCheckPutFunction = 46; +#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; + static const int patchOffsetPutByIdExternalLoad = 16; + static const int patchLengthPutByIdExternalLoad = 4; + static const int patchOffsetPutByIdPropertyMapOffset = 20; + // These architecture specific value are used to enable patching - see comment on op_get_by_id. + static const int patchOffsetGetByIdStructure = 4; + static const int patchOffsetGetByIdBranchToSlowCase = 16; + static const int patchOffsetGetByIdExternalLoad = 16; + static const int patchLengthGetByIdExternalLoad = 4; + static const int patchOffsetGetByIdPropertyMapOffset = 20; + static const int patchOffsetGetByIdPutResult = 28; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 36; +#endif + static const int patchOffsetOpCallCompareToJump = 12; + + static const int patchOffsetMethodCheckProtoObj = 12; + static const int patchOffsetMethodCheckProtoStruct = 20; + static const int patchOffsetMethodCheckPutFunction = 32; +#endif +#endif // USE(JSVALUE32_64) + +#if PLATFORM(ARM_TRADITIONAL) + // sequenceOpCall + static const int sequenceOpCallInstructionSpace = 12; + static const int sequenceOpCallConstantSpace = 2; + // sequenceMethodCheck + static const int sequenceMethodCheckInstructionSpace = 40; + static const int sequenceMethodCheckConstantSpace = 6; + // sequenceGetByIdHotPath + static const int sequenceGetByIdHotPathInstructionSpace = 28; + static const int sequenceGetByIdHotPathConstantSpace = 3; + // sequenceGetByIdSlowCase + static const int sequenceGetByIdSlowCaseInstructionSpace = 40; + static const int sequenceGetByIdSlowCaseConstantSpace = 2; + // sequencePutById + static const int sequencePutByIdInstructionSpace = 28; + static const int sequencePutByIdConstantSpace = 3; +#endif + +#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL +#define BEGIN_UNINTERRUPTED_SEQUENCE(name) beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace) +#define END_UNINTERRUPTED_SEQUENCE(name) endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace) + + void beginUninterruptedSequence(int, int); + void endUninterruptedSequence(int, int); + +#else +#define BEGIN_UNINTERRUPTED_SEQUENCE(name) +#define END_UNINTERRUPTED_SEQUENCE(name) +#endif + + void emit_op_add(Instruction*); + void emit_op_bitand(Instruction*); + void emit_op_bitnot(Instruction*); + void emit_op_bitor(Instruction*); + void emit_op_bitxor(Instruction*); void emit_op_call(Instruction*); void emit_op_call_eval(Instruction*); - void emit_op_method_check(Instruction*); - void emit_op_load_varargs(Instruction*); void emit_op_call_varargs(Instruction*); + void emit_op_catch(Instruction*); void emit_op_construct(Instruction*); + void emit_op_construct_verify(Instruction*); + void emit_op_convert_this(Instruction*); + void emit_op_create_arguments(Instruction*); + void emit_op_debug(Instruction*); + void emit_op_del_by_id(Instruction*); + void emit_op_div(Instruction*); + void emit_op_end(Instruction*); + void emit_op_enter(Instruction*); + void emit_op_enter_with_activation(Instruction*); + void emit_op_eq(Instruction*); + void emit_op_eq_null(Instruction*); + void emit_op_get_by_id(Instruction*); + void emit_op_get_by_val(Instruction*); void emit_op_get_global_var(Instruction*); - void emit_op_put_global_var(Instruction*); void emit_op_get_scoped_var(Instruction*); - void emit_op_put_scoped_var(Instruction*); - void emit_op_tear_off_activation(Instruction*); - void emit_op_tear_off_arguments(Instruction*); - void emit_op_ret(Instruction*); - void emit_op_new_array(Instruction*); - void emit_op_resolve(Instruction*); - void emit_op_construct_verify(Instruction*); - void emit_op_to_primitive(Instruction*); - void emit_op_strcat(Instruction*); - void emit_op_resolve_func(Instruction*); - void emit_op_loop_if_true(Instruction*); - void emit_op_resolve_base(Instruction*); - void emit_op_resolve_skip(Instruction*); - void emit_op_resolve_global(Instruction*); - void emit_op_not(Instruction*); - void emit_op_jfalse(Instruction*); + void emit_op_init_arguments(Instruction*); + void emit_op_instanceof(Instruction*); void emit_op_jeq_null(Instruction*); + void emit_op_jfalse(Instruction*); + void emit_op_jmp(Instruction*); + void emit_op_jmp_scopes(Instruction*); void emit_op_jneq_null(Instruction*); void emit_op_jneq_ptr(Instruction*); - void emit_op_unexpected_load(Instruction*); + void emit_op_jnless(Instruction*); + void emit_op_jnlesseq(Instruction*); void emit_op_jsr(Instruction*); - void emit_op_sret(Instruction*); - void emit_op_eq(Instruction*); - void emit_op_bitnot(Instruction*); - void emit_op_resolve_with_base(Instruction*); - void emit_op_new_func_exp(Instruction*); void emit_op_jtrue(Instruction*); + void emit_op_load_varargs(Instruction*); + void emit_op_loop(Instruction*); + void emit_op_loop_if_less(Instruction*); + void emit_op_loop_if_lesseq(Instruction*); + void emit_op_loop_if_true(Instruction*); + void emit_op_lshift(Instruction*); + void emit_op_method_check(Instruction*); + void emit_op_mod(Instruction*); + void emit_op_mov(Instruction*); + void emit_op_mul(Instruction*); + void emit_op_negate(Instruction*); void emit_op_neq(Instruction*); - void emit_op_bitxor(Instruction*); + void emit_op_neq_null(Instruction*); + void emit_op_new_array(Instruction*); + void emit_op_new_error(Instruction*); + void emit_op_new_func(Instruction*); + void emit_op_new_func_exp(Instruction*); + void emit_op_new_object(Instruction*); void emit_op_new_regexp(Instruction*); - void emit_op_bitor(Instruction*); - void emit_op_throw(Instruction*); void emit_op_next_pname(Instruction*); - void emit_op_push_scope(Instruction*); - void emit_op_pop_scope(Instruction*); - void emit_op_stricteq(Instruction*); + void emit_op_not(Instruction*); void emit_op_nstricteq(Instruction*); - void emit_op_to_jsnumber(Instruction*); + void emit_op_pop_scope(Instruction*); + void emit_op_post_dec(Instruction*); + void emit_op_post_inc(Instruction*); + void emit_op_pre_dec(Instruction*); + void emit_op_pre_inc(Instruction*); + void emit_op_profile_did_call(Instruction*); + void emit_op_profile_will_call(Instruction*); void emit_op_push_new_scope(Instruction*); - void emit_op_catch(Instruction*); - void emit_op_jmp_scopes(Instruction*); - void emit_op_switch_imm(Instruction*); + void emit_op_push_scope(Instruction*); + void emit_op_put_by_id(Instruction*); + void emit_op_put_by_index(Instruction*); + void emit_op_put_by_val(Instruction*); + void emit_op_put_getter(Instruction*); + void emit_op_put_global_var(Instruction*); + void emit_op_put_scoped_var(Instruction*); + void emit_op_put_setter(Instruction*); + void emit_op_resolve(Instruction*); + void emit_op_resolve_base(Instruction*); + void emit_op_resolve_global(Instruction*); + void emit_op_resolve_skip(Instruction*); + void emit_op_resolve_with_base(Instruction*); + void emit_op_ret(Instruction*); + void emit_op_rshift(Instruction*); + void emit_op_sret(Instruction*); + void emit_op_strcat(Instruction*); + void emit_op_stricteq(Instruction*); + void emit_op_sub(Instruction*); void emit_op_switch_char(Instruction*); + void emit_op_switch_imm(Instruction*); void emit_op_switch_string(Instruction*); - void emit_op_new_error(Instruction*); - void emit_op_debug(Instruction*); - void emit_op_eq_null(Instruction*); - void emit_op_neq_null(Instruction*); - void emit_op_enter(Instruction*); - void emit_op_enter_with_activation(Instruction*); - void emit_op_init_arguments(Instruction*); - void emit_op_create_arguments(Instruction*); - void emit_op_convert_this(Instruction*); - void emit_op_profile_will_call(Instruction*); - void emit_op_profile_did_call(Instruction*); + void emit_op_tear_off_activation(Instruction*); + void emit_op_tear_off_arguments(Instruction*); + void emit_op_throw(Instruction*); + void emit_op_to_jsnumber(Instruction*); + void emit_op_to_primitive(Instruction*); + void emit_op_unexpected_load(Instruction*); - void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_construct_verify(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_val(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&); + void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_negate(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_neq(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_resolve_global(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&); -#if ENABLE(JIT_OPTIMIZE_ARITHMETIC) - void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); - void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); -#endif - - void emitGetVirtualRegister(int src, RegisterID dst); - void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2); - void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0); - + /* These functions are deprecated: Please use JITStubCall instead. */ void emitPutJITStubArg(RegisterID src, unsigned argumentNumber); +#if USE(JSVALUE32_64) + void emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber); + void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2); +#else void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch); +#endif void emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber); void emitPutJITStubArgConstant(void* value, unsigned argumentNumber); void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst); @@ -606,30 +810,8 @@ namespace JSC { void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister); JSValue getConstantOperand(unsigned src); - int32_t getConstantOperandImmediateInt(unsigned src); bool isOperandConstantImmediateInt(unsigned src); - Jump emitJumpIfJSCell(RegisterID); - Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID); - void emitJumpSlowCaseIfJSCell(RegisterID); - Jump emitJumpIfNotJSCell(RegisterID); - void emitJumpSlowCaseIfNotJSCell(RegisterID); - void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg); -#if USE(ALTERNATE_JSIMMEDIATE) - JIT::Jump emitJumpIfImmediateNumber(RegisterID); - JIT::Jump emitJumpIfNotImmediateNumber(RegisterID); -#else - JIT::Jump emitJumpIfImmediateNumber(RegisterID reg) - { - return emitJumpIfImmediateInteger(reg); - } - - JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg) - { - return emitJumpIfNotImmediateInteger(reg); - } -#endif - Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter) { return iter++->from; @@ -641,43 +823,22 @@ namespace JSC { } void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg); - JIT::Jump emitJumpIfImmediateInteger(RegisterID); - JIT::Jump emitJumpIfNotImmediateInteger(RegisterID); - JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); - void emitJumpSlowCaseIfNotImmediateInteger(RegisterID); - void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); - Jump checkStructure(RegisterID reg, Structure* structure); -#if !USE(ALTERNATE_JSIMMEDIATE) - void emitFastArithDeTagImmediate(RegisterID); - Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID); -#endif - void emitFastArithReTagImmediate(RegisterID src, RegisterID dest); - void emitFastArithImmToInt(RegisterID); - void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest); - - void emitTagAsBoolImmediate(RegisterID reg); - void restoreArgumentReference(); void restoreArgumentReferenceForTrampoline(); Call emitNakedCall(CodePtr function = CodePtr()); + void preserveReturnAddressAfterCall(RegisterID); void restoreReturnAddressBeforeReturn(RegisterID); void restoreReturnAddressBeforeReturn(Address); - void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst); - void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index); - void emitTimeoutCheck(); #ifndef NDEBUG void printBytecodeOperandTypes(unsigned src1, unsigned src2); #endif - void killLastResultRegister(); - - #if ENABLE(SAMPLING_FLAGS) void setSamplingFlag(int32_t); void clearSamplingFlag(int32_t); @@ -713,15 +874,29 @@ namespace JSC { Vector<SlowCaseEntry> m_slowCases; Vector<SwitchRecord> m_switches; - int m_lastResultBytecodeRegister; - unsigned m_jumpTargetsPosition; - unsigned m_propertyAccessInstructionIndex; unsigned m_globalResolveInfoIndex; unsigned m_callLinkInfoIndex; - } JIT_CLASS_ALIGNMENT; -} +#if USE(JSVALUE32_64) + unsigned m_jumpTargetIndex; + unsigned m_mappedBytecodeIndex; + unsigned m_mappedVirtualRegisterIndex; + RegisterID m_mappedTag; + RegisterID m_mappedPayload; +#else + int m_lastResultBytecodeRegister; + unsigned m_jumpTargetsPosition; +#endif + +#ifndef NDEBUG +#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL + Label m_uninterruptedInstructionSequenceBegin; + int m_uninterruptedConstantSequenceBegin; +#endif +#endif + } JIT_CLASS_ALIGNMENT; +} // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp index 15808e2..3be13cb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp @@ -41,11 +41,1095 @@ #include <stdio.h> #endif - using namespace std; namespace JSC { +#if USE(JSVALUE32_64) + +void JIT::emit_op_negate(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + + Jump srcNotInt = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + addSlowCase(branch32(Equal, regT0, Imm32(0))); + + neg32(regT0); + emitStoreInt32(dst, regT0, (dst == src)); + + Jump end = jump(); + + srcNotInt.link(this); + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + xor32(Imm32(1 << 31), regT1); + store32(regT1, tagFor(dst)); + if (dst != src) + store32(regT0, payloadFor(dst)); + + end.link(this); +} + +void JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + + linkSlowCase(iter); // 0 check + linkSlowCase(iter); // double check + + JITStubCall stubCall(this, cti_op_negate); + stubCall.addArgument(regT1, regT0); + stubCall.call(dst); +} + +void JIT::emit_op_jnless(Instruction* currentInstruction) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + JumpList notInt32Op1; + JumpList notInt32Op2; + + // Int32 less. + 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); + } 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); + } 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); + } + + if (!supportsFloatingPoint()) { + addSlowCase(notInt32Op1); + addSlowCase(notInt32Op2); + return; + } + Jump end = jump(); + + // Double less. + emitBinaryDoubleOp(op_jnless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); + end.link(this); +} + +void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + if (!supportsFloatingPoint()) { + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + } else { + if (!isOperandConstantImmediateInt(op1)) { + linkSlowCase(iter); // double check + linkSlowCase(iter); // int32 check + } + if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // double check + } + + JITStubCall stubCall(this, cti_op_jless); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(); + emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); +} + +void JIT::emit_op_jnlesseq(Instruction* currentInstruction) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + JumpList notInt32Op1; + JumpList notInt32Op2; + + // Int32 less. + 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); + } 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); + } 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); + } + + if (!supportsFloatingPoint()) { + addSlowCase(notInt32Op1); + addSlowCase(notInt32Op2); + return; + } + Jump end = jump(); + + // Double less. + emitBinaryDoubleOp(op_jnlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); + end.link(this); +} + +void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + if (!supportsFloatingPoint()) { + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + } else { + if (!isOperandConstantImmediateInt(op1)) { + linkSlowCase(iter); // double check + linkSlowCase(iter); // int32 check + } + if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // double check + } + + JITStubCall stubCall(this, cti_op_jlesseq); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(); + emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); +} + +// LeftShift (<<) + +void JIT::emit_op_lshift(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (isOperandConstantImmediateInt(op2)) { + emitLoad(op1, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0); + emitStoreInt32(dst, regT0, dst == op1); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + if (!isOperandConstantImmediateInt(op1)) + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + lshift32(regT2, regT0); + emitStoreInt32(dst, regT0, dst == op1 || dst == op2); +} + +void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_lshift); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// RightShift (>>) + +void JIT::emit_op_rshift(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (isOperandConstantImmediateInt(op2)) { + emitLoad(op1, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + rshift32(Imm32(getConstantOperand(op2).asInt32()), regT0); + emitStoreInt32(dst, regT0, dst == op1); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + if (!isOperandConstantImmediateInt(op1)) + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + rshift32(regT2, regT0); + emitStoreInt32(dst, regT0, dst == op1 || dst == op2); +} + +void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_rshift); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// BitAnd (&) + +void JIT::emit_op_bitand(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + unsigned op; + int32_t constant; + if (getOperandConstantImmediateInt(op1, op2, op, constant)) { + emitLoad(op, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + and32(Imm32(constant), regT0); + emitStoreInt32(dst, regT0, (op == dst)); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + and32(regT2, regT0); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); +} + +void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_bitand); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// BitOr (|) + +void JIT::emit_op_bitor(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + unsigned op; + int32_t constant; + if (getOperandConstantImmediateInt(op1, op2, op, constant)) { + emitLoad(op, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + or32(Imm32(constant), regT0); + emitStoreInt32(dst, regT0, (op == dst)); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + or32(regT2, regT0); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); +} + +void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_bitor); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// BitXor (^) + +void JIT::emit_op_bitxor(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + unsigned op; + int32_t constant; + if (getOperandConstantImmediateInt(op1, op2, op, constant)) { + emitLoad(op, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + xor32(Imm32(constant), regT0); + emitStoreInt32(dst, regT0, (op == dst)); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + xor32(regT2, regT0); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); +} + +void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_bitxor); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// BitNot (~) + +void JIT::emit_op_bitnot(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + + not32(regT0); + emitStoreInt32(dst, regT0, (dst == src)); +} + +void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_bitnot); + stubCall.addArgument(regT1, regT0); + stubCall.call(dst); +} + +// PostInc (i++) + +void JIT::emit_op_post_inc(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned srcDst = currentInstruction[2].u.operand; + + emitLoad(srcDst, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + + if (dst == srcDst) // x = x++ is a noop for ints. + return; + + emitStoreInt32(dst, regT0); + + addSlowCase(branchAdd32(Overflow, Imm32(1), regT0)); + emitStoreInt32(srcDst, regT0, true); +} + +void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned srcDst = currentInstruction[2].u.operand; + + linkSlowCase(iter); // int32 check + if (dst != srcDst) + linkSlowCase(iter); // overflow check + + JITStubCall stubCall(this, cti_op_post_inc); + stubCall.addArgument(srcDst); + stubCall.addArgument(Imm32(srcDst)); + stubCall.call(dst); +} + +// PostDec (i--) + +void JIT::emit_op_post_dec(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned srcDst = currentInstruction[2].u.operand; + + emitLoad(srcDst, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + + if (dst == srcDst) // x = x-- is a noop for ints. + return; + + emitStoreInt32(dst, regT0); + + addSlowCase(branchSub32(Overflow, Imm32(1), regT0)); + emitStoreInt32(srcDst, regT0, true); +} + +void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned srcDst = currentInstruction[2].u.operand; + + linkSlowCase(iter); // int32 check + if (dst != srcDst) + linkSlowCase(iter); // overflow check + + JITStubCall stubCall(this, cti_op_post_dec); + stubCall.addArgument(srcDst); + stubCall.addArgument(Imm32(srcDst)); + stubCall.call(dst); +} + +// PreInc (++i) + +void JIT::emit_op_pre_inc(Instruction* currentInstruction) +{ + unsigned srcDst = currentInstruction[1].u.operand; + + emitLoad(srcDst, regT1, regT0); + + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branchAdd32(Overflow, Imm32(1), regT0)); + emitStoreInt32(srcDst, regT0, true); +} + +void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned srcDst = currentInstruction[1].u.operand; + + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // overflow check + + JITStubCall stubCall(this, cti_op_pre_inc); + stubCall.addArgument(srcDst); + stubCall.call(srcDst); +} + +// PreDec (--i) + +void JIT::emit_op_pre_dec(Instruction* currentInstruction) +{ + unsigned srcDst = currentInstruction[1].u.operand; + + emitLoad(srcDst, regT1, regT0); + + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branchSub32(Overflow, Imm32(1), regT0)); + emitStoreInt32(srcDst, regT0, true); +} + +void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned srcDst = currentInstruction[1].u.operand; + + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // overflow check + + JITStubCall stubCall(this, cti_op_pre_dec); + stubCall.addArgument(srcDst); + stubCall.call(srcDst); +} + +// Addition (+) + +void JIT::emit_op_add(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + JumpList notInt32Op1; + JumpList notInt32Op2; + + unsigned op; + int32_t constant; + if (getOperandConstantImmediateInt(op1, op2, op, constant)) { + emitAdd32Constant(dst, op, constant, op == op1 ? types.first() : types.second()); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + + // Int32 case. + addSlowCase(branchAdd32(Overflow, regT2, regT0)); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); + + if (!supportsFloatingPoint()) { + addSlowCase(notInt32Op1); + addSlowCase(notInt32Op2); + return; + } + Jump end = jump(); + + // Double case. + emitBinaryDoubleOp(op_add, dst, op1, op2, types, notInt32Op1, notInt32Op2); + end.link(this); +} + +void JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType) +{ + // Int32 case. + emitLoad(op, regT1, regT0); + Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + addSlowCase(branchAdd32(Overflow, Imm32(constant), regT0)); + emitStoreInt32(dst, regT0, (op == dst)); + + // Double case. + if (!supportsFloatingPoint()) { + addSlowCase(notInt32); + return; + } + Jump end = jump(); + + notInt32.link(this); + if (!opType.definitelyIsNumber()) + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + move(Imm32(constant), regT2); + convertInt32ToDouble(regT2, fpRegT0); + emitLoadDouble(op, fpRegT1); + addDouble(fpRegT1, fpRegT0); + emitStoreDouble(dst, fpRegT0); + + end.link(this); +} + +void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + unsigned op; + int32_t constant; + if (getOperandConstantImmediateInt(op1, op2, op, constant)) { + linkSlowCase(iter); // overflow check + + if (!supportsFloatingPoint()) { + linkSlowCase(iter); // non-sse case + return; + } + + ResultType opType = op == op1 ? types.first() : types.second(); + if (!opType.definitelyIsNumber()) + linkSlowCase(iter); // double check + } else { + linkSlowCase(iter); // overflow check + + if (!supportsFloatingPoint()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + } else { + if (!types.first().definitelyIsNumber()) + linkSlowCase(iter); // double check + + if (!types.second().definitelyIsNumber()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // double check + } + } + } + + JITStubCall stubCall(this, cti_op_add); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// Subtraction (-) + +void JIT::emit_op_sub(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + JumpList notInt32Op1; + JumpList notInt32Op2; + + if (isOperandConstantImmediateInt(op2)) { + emitSub32Constant(dst, op1, getConstantOperand(op2).asInt32(), types.first()); + return; + } + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + + // Int32 case. + addSlowCase(branchSub32(Overflow, regT2, regT0)); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); + + if (!supportsFloatingPoint()) { + addSlowCase(notInt32Op1); + addSlowCase(notInt32Op2); + return; + } + Jump end = jump(); + + // Double case. + emitBinaryDoubleOp(op_sub, dst, op1, op2, types, notInt32Op1, notInt32Op2); + end.link(this); +} + +void JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType) +{ + // Int32 case. + emitLoad(op, regT1, regT0); + Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + addSlowCase(branchSub32(Overflow, Imm32(constant), regT0)); + emitStoreInt32(dst, regT0, (op == dst)); + + // Double case. + if (!supportsFloatingPoint()) { + addSlowCase(notInt32); + return; + } + Jump end = jump(); + + notInt32.link(this); + if (!opType.definitelyIsNumber()) + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + move(Imm32(constant), regT2); + convertInt32ToDouble(regT2, fpRegT0); + emitLoadDouble(op, fpRegT1); + subDouble(fpRegT0, fpRegT1); + emitStoreDouble(dst, fpRegT1); + + end.link(this); +} + +void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + if (isOperandConstantImmediateInt(op2)) { + linkSlowCase(iter); // overflow check + + if (!supportsFloatingPoint() || !types.first().definitelyIsNumber()) + linkSlowCase(iter); // int32 or double check + } else { + linkSlowCase(iter); // overflow check + + if (!supportsFloatingPoint()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + } else { + if (!types.first().definitelyIsNumber()) + linkSlowCase(iter); // double check + + if (!types.second().definitelyIsNumber()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // double check + } + } + } + + JITStubCall stubCall(this, cti_op_sub); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters) +{ + JumpList end; + + if (!notInt32Op1.empty()) { + // Double case 1: Op1 is not int32; Op2 is unknown. + notInt32Op1.link(this); + + ASSERT(op1IsInRegisters); + + // Verify Op1 is double. + if (!types.first().definitelyIsNumber()) + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + if (!op2IsInRegisters) + emitLoad(op2, regT3, regT2); + + Jump doubleOp2 = branch32(Below, regT3, Imm32(JSValue::LowestTag)); + + if (!types.second().definitelyIsNumber()) + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + + convertInt32ToDouble(regT2, fpRegT0); + Jump doTheMath = jump(); + + // Load Op2 as double into double register. + doubleOp2.link(this); + emitLoadDouble(op2, fpRegT0); + + // Do the math. + doTheMath.link(this); + switch (opcodeID) { + case op_mul: + emitLoadDouble(op1, fpRegT2); + mulDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_add: + emitLoadDouble(op1, fpRegT2); + addDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_sub: + emitLoadDouble(op1, fpRegT1); + subDouble(fpRegT0, fpRegT1); + emitStoreDouble(dst, fpRegT1); + break; + case op_div: + emitLoadDouble(op1, fpRegT1); + divDouble(fpRegT0, fpRegT1); + emitStoreDouble(dst, fpRegT1); + break; + case op_jnless: + emitLoadDouble(op1, fpRegT2); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst + 3); + break; + case op_jnlesseq: + emitLoadDouble(op1, fpRegT2); + addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst + 3); + break; + default: + ASSERT_NOT_REACHED(); + } + + if (!notInt32Op2.empty()) + end.append(jump()); + } + + if (!notInt32Op2.empty()) { + // Double case 2: Op1 is int32; Op2 is not int32. + notInt32Op2.link(this); + + ASSERT(op2IsInRegisters); + + if (!op1IsInRegisters) + emitLoadPayload(op1, regT0); + + convertInt32ToDouble(regT0, fpRegT0); + + // Verify op2 is double. + if (!types.second().definitelyIsNumber()) + addSlowCase(branch32(Above, regT3, Imm32(JSValue::LowestTag))); + + // Do the math. + switch (opcodeID) { + case op_mul: + emitLoadDouble(op2, fpRegT2); + mulDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_add: + emitLoadDouble(op2, fpRegT2); + addDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_sub: + emitLoadDouble(op2, fpRegT2); + subDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_div: + emitLoadDouble(op2, fpRegT2); + divDouble(fpRegT2, fpRegT0); + emitStoreDouble(dst, fpRegT0); + break; + case op_jnless: + emitLoadDouble(op2, fpRegT1); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst + 3); + break; + case op_jnlesseq: + emitLoadDouble(op2, fpRegT1); + addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst + 3); + break; + default: + ASSERT_NOT_REACHED(); + } + } + + end.link(this); +} + +// Multiplication (*) + +void JIT::emit_op_mul(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + JumpList notInt32Op1; + JumpList notInt32Op2; + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + + // Int32 case. + move(regT0, regT3); + addSlowCase(branchMul32(Overflow, regT2, regT0)); + addSlowCase(branchTest32(Zero, regT0)); + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); + + if (!supportsFloatingPoint()) { + addSlowCase(notInt32Op1); + addSlowCase(notInt32Op2); + return; + } + Jump end = jump(); + + // Double case. + emitBinaryDoubleOp(op_mul, dst, op1, op2, types, notInt32Op1, notInt32Op2); + end.link(this); +} + +void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + Jump overflow = getSlowCase(iter); // overflow check + linkSlowCase(iter); // zero result check + + Jump negZero = branchOr32(Signed, regT2, regT3); + emitStoreInt32(dst, Imm32(0), (op1 == dst || op2 == dst)); + + emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_mul)); + + negZero.link(this); + overflow.link(this); + + if (!supportsFloatingPoint()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + } + + if (supportsFloatingPoint()) { + if (!types.first().definitelyIsNumber()) + linkSlowCase(iter); // double check + + if (!types.second().definitelyIsNumber()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // double check + } + } + + Label jitStubCall(this); + JITStubCall stubCall(this, cti_op_mul); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// Division (/) + +void JIT::emit_op_div(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + if (!supportsFloatingPoint()) { + addSlowCase(jump()); + return; + } + + // Int32 divide. + JumpList notInt32Op1; + JumpList notInt32Op2; + + JumpList end; + + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + + notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); + + convertInt32ToDouble(regT0, fpRegT0); + convertInt32ToDouble(regT2, fpRegT1); + divDouble(fpRegT1, fpRegT0); + + JumpList doubleResult; + if (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) { + m_assembler.cvttsd2si_rr(fpRegT0, regT0); + convertInt32ToDouble(regT0, fpRegT1); + m_assembler.ucomisd_rr(fpRegT1, fpRegT0); + + doubleResult.append(m_assembler.jne()); + doubleResult.append(m_assembler.jp()); + + doubleResult.append(branchTest32(Zero, regT0)); + + // Int32 result. + emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); + end.append(jump()); + } + + // Double result. + doubleResult.link(this); + emitStoreDouble(dst, fpRegT0); + end.append(jump()); + + // Double divide. + emitBinaryDoubleOp(op_div, dst, op1, op2, types, notInt32Op1, notInt32Op2); + end.link(this); +} + +void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + if (!supportsFloatingPoint()) + linkSlowCase(iter); + else { + if (!types.first().definitelyIsNumber()) + linkSlowCase(iter); // double check + + if (!types.second().definitelyIsNumber()) { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // double check + } + } + + JITStubCall stubCall(this, cti_op_div); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +// Mod (%) + +/* ------------------------------ BEGIN: OP_MOD ------------------------------ */ + +#if PLATFORM(X86) || PLATFORM(X86_64) + +void JIT::emit_op_mod(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) { + emitLoad(op1, X86Registers::edx, X86Registers::eax); + move(Imm32(getConstantOperand(op2).asInt32()), X86Registers::ecx); + addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag))); + if (getConstantOperand(op2).asInt32() == -1) + addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC + } else { + emitLoad2(op1, X86Registers::edx, X86Registers::eax, op2, X86Registers::ebx, X86Registers::ecx); + addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, X86Registers::ebx, Imm32(JSValue::Int32Tag))); + + addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC + addSlowCase(branch32(Equal, X86Registers::ecx, Imm32(0))); // divide by 0 + } + + move(X86Registers::eax, X86Registers::ebx); // Save dividend payload, in case of 0. + m_assembler.cdq(); + m_assembler.idivl_r(X86Registers::ecx); + + // If the remainder is zero and the dividend is negative, the result is -0. + Jump storeResult1 = branchTest32(NonZero, X86Registers::edx); + Jump storeResult2 = branchTest32(Zero, X86Registers::ebx, Imm32(0x80000000)); // not negative + emitStore(dst, jsNumber(m_globalData, -0.0)); + Jump end = jump(); + + storeResult1.link(this); + storeResult2.link(this); + emitStoreInt32(dst, X86Registers::edx, (op1 == dst || op2 == dst)); + end.link(this); +} + +void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) { + linkSlowCase(iter); // int32 check + if (getConstantOperand(op2).asInt32() == -1) + linkSlowCase(iter); // 0x80000000 check + } else { + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // 0 check + linkSlowCase(iter); // 0x80000000 check + } + + JITStubCall stubCall(this, cti_op_mod); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +#else // PLATFORM(X86) || PLATFORM(X86_64) + +void JIT::emit_op_mod(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_mod); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); +} + +void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&) +{ +} + +#endif // PLATFORM(X86) || PLATFORM(X86_64) + +/* ------------------------------ END: OP_MOD ------------------------------ */ + +#else // USE(JSVALUE32_64) + void JIT::emit_op_lshift(Instruction* currentInstruction) { unsigned result = currentInstruction[1].u.operand; @@ -64,7 +1148,7 @@ void JIT::emit_op_lshift(Instruction* currentInstruction) and32(Imm32(0x1f), regT2); #endif lshift32(regT2, regT0); -#if !USE(ALTERNATE_JSIMMEDIATE) +#if !USE(JSVALUE64) addSlowCase(branchAdd32(Overflow, regT0, regT0)); signExtend32ToPtr(regT0, regT0); #endif @@ -78,7 +1162,7 @@ void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEnt unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) UNUSED_PARAM(op1); UNUSED_PARAM(op2); linkSlowCase(iter); @@ -92,7 +1176,7 @@ void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEnt notImm1.link(this); notImm2.link(this); #endif - JITStubCall stubCall(this, JITStubs::cti_op_lshift); + JITStubCall stubCall(this, cti_op_lshift); stubCall.addArgument(regT0); stubCall.addArgument(regT2); stubCall.call(result); @@ -109,7 +1193,7 @@ void JIT::emit_op_rshift(Instruction* currentInstruction) emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); // Mask with 0x1f as per ecma-262 11.7.2 step 7. -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0); #else rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0); @@ -118,14 +1202,14 @@ void JIT::emit_op_rshift(Instruction* currentInstruction) emitGetVirtualRegisters(op1, regT0, op2, regT2); if (supportsFloatingPointTruncate()) { Jump lhsIsInt = emitJumpIfImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) - // supportsFloatingPoint() && USE(ALTERNATE_JSIMMEDIATE) => 3 SlowCases +#if USE(JSVALUE64) + // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases addSlowCase(emitJumpIfNotImmediateNumber(regT0)); addPtr(tagTypeNumberRegister, regT0); movePtrToDouble(regT0, fpRegT0); addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0)); #else - // supportsFloatingPoint() && !USE(ALTERNATE_JSIMMEDIATE) => 5 SlowCases (of which 1 IfNotJSCell) + // supportsFloatingPoint() && !USE(JSVALUE64) => 5 SlowCases (of which 1 IfNotJSCell) emitJumpSlowCaseIfNotJSCell(regT0, op1); addSlowCase(checkStructure(regT0, m_globalData->numberStructure.get())); loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0); @@ -145,13 +1229,13 @@ void JIT::emit_op_rshift(Instruction* currentInstruction) // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction. and32(Imm32(0x1f), regT2); #endif -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) rshift32(regT2, regT0); #else rshiftPtr(regT2, regT0); #endif } -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) emitFastArithIntToImmNoCheck(regT0, regT0); #else orPtr(Imm32(JSImmediate::TagTypeNumber), regT0); @@ -165,7 +1249,7 @@ void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEnt unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; - JITStubCall stubCall(this, JITStubs::cti_op_rshift); + JITStubCall stubCall(this, cti_op_rshift); if (isOperandConstantImmediateInt(op2)) { linkSlowCase(iter); @@ -173,7 +1257,7 @@ void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(op2, regT2); } else { if (supportsFloatingPointTruncate()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) linkSlowCase(iter); linkSlowCase(iter); linkSlowCase(iter); @@ -214,7 +1298,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op2)) { emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op2imm = getConstantOperandImmediateInt(op2); #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); @@ -223,7 +1307,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op1imm = getConstantOperandImmediateInt(op1); #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); @@ -253,7 +1337,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT0); addPtr(tagTypeNumberRegister, regT0); movePtrToDouble(regT0, fpRegT0); @@ -266,7 +1350,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0); #endif - int32_t op2imm = getConstantOperand(op2).getInt32Fast();; + int32_t op2imm = getConstantOperand(op2).asInt32();; move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); @@ -275,7 +1359,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); #else if (!m_codeBlock->isKnownNotImmediate(op1)) @@ -284,7 +1368,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt #endif } - JITStubCall stubCall(this, JITStubs::cti_op_jless); + JITStubCall stubCall(this, cti_op_jless); stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); @@ -294,7 +1378,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT1); addPtr(tagTypeNumberRegister, regT1); movePtrToDouble(regT1, fpRegT1); @@ -307,7 +1391,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - int32_t op1imm = getConstantOperand(op1).getInt32Fast();; + int32_t op1imm = getConstantOperand(op1).asInt32();; move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); @@ -316,7 +1400,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); #else if (!m_codeBlock->isKnownNotImmediate(op2)) @@ -325,7 +1409,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt #endif } - JITStubCall stubCall(this, JITStubs::cti_op_jless); + JITStubCall stubCall(this, cti_op_jless); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); @@ -335,7 +1419,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT0); Jump fail2 = emitJumpIfNotImmediateNumber(regT1); Jump fail3 = emitJumpIfImmediateInteger(regT1); @@ -362,7 +1446,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); fail2.link(this); fail3.link(this); @@ -377,7 +1461,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt } linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_jless); + JITStubCall stubCall(this, cti_op_jless); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); @@ -399,7 +1483,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op2)) { emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op2imm = getConstantOperandImmediateInt(op2); #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); @@ -408,7 +1492,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op1imm = getConstantOperandImmediateInt(op1); #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); @@ -438,7 +1522,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT0); addPtr(tagTypeNumberRegister, regT0); movePtrToDouble(regT0, fpRegT0); @@ -451,7 +1535,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0); #endif - int32_t op2imm = getConstantOperand(op2).getInt32Fast();; + int32_t op2imm = getConstantOperand(op2).asInt32();; move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); @@ -460,7 +1544,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); #else if (!m_codeBlock->isKnownNotImmediate(op1)) @@ -469,7 +1553,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE #endif } - JITStubCall stubCall(this, JITStubs::cti_op_jlesseq); + JITStubCall stubCall(this, cti_op_jlesseq); stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); @@ -479,7 +1563,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT1); addPtr(tagTypeNumberRegister, regT1); movePtrToDouble(regT1, fpRegT1); @@ -492,7 +1576,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - int32_t op1imm = getConstantOperand(op1).getInt32Fast();; + int32_t op1imm = getConstantOperand(op1).asInt32();; move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); @@ -501,7 +1585,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); #else if (!m_codeBlock->isKnownNotImmediate(op2)) @@ -510,7 +1594,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE #endif } - JITStubCall stubCall(this, JITStubs::cti_op_jlesseq); + JITStubCall stubCall(this, cti_op_jlesseq); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); @@ -520,7 +1604,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE linkSlowCase(iter); if (supportsFloatingPoint()) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) Jump fail1 = emitJumpIfNotImmediateNumber(regT0); Jump fail2 = emitJumpIfNotImmediateNumber(regT1); Jump fail3 = emitJumpIfImmediateInteger(regT1); @@ -547,7 +1631,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) fail1.link(this); fail2.link(this); fail3.link(this); @@ -562,7 +1646,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE } linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_jlesseq); + JITStubCall stubCall(this, cti_op_jlesseq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); @@ -579,7 +1663,7 @@ void JIT::emit_op_bitand(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t imm = getConstantOperandImmediateInt(op1); andPtr(Imm32(imm), regT0); if (imm >= 0) @@ -590,7 +1674,7 @@ void JIT::emit_op_bitand(Instruction* currentInstruction) } else if (isOperandConstantImmediateInt(op2)) { emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t imm = getConstantOperandImmediateInt(op2); andPtr(Imm32(imm), regT0); if (imm >= 0) @@ -614,17 +1698,17 @@ void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEnt linkSlowCase(iter); if (isOperandConstantImmediateInt(op1)) { - JITStubCall stubCall(this, JITStubs::cti_op_bitand); + JITStubCall stubCall(this, cti_op_bitand); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(result); } else if (isOperandConstantImmediateInt(op2)) { - JITStubCall stubCall(this, JITStubs::cti_op_bitand); + JITStubCall stubCall(this, cti_op_bitand); stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(result); } else { - JITStubCall stubCall(this, JITStubs::cti_op_bitand); + JITStubCall stubCall(this, cti_op_bitand); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(result); @@ -639,7 +1723,7 @@ void JIT::emit_op_post_inc(Instruction* currentInstruction) emitGetVirtualRegister(srcDst, regT0); move(regT0, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) addSlowCase(branchAdd32(Overflow, Imm32(1), regT1)); emitFastArithIntToImmNoCheck(regT1, regT1); #else @@ -657,7 +1741,7 @@ void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseE linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_post_inc); + JITStubCall stubCall(this, cti_op_post_inc); stubCall.addArgument(regT0); stubCall.addArgument(Imm32(srcDst)); stubCall.call(result); @@ -671,7 +1755,7 @@ void JIT::emit_op_post_dec(Instruction* currentInstruction) emitGetVirtualRegister(srcDst, regT0); move(regT0, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) addSlowCase(branchSub32(Zero, Imm32(1), regT1)); emitFastArithIntToImmNoCheck(regT1, regT1); #else @@ -689,7 +1773,7 @@ void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseE linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_post_dec); + JITStubCall stubCall(this, cti_op_post_dec); stubCall.addArgument(regT0); stubCall.addArgument(Imm32(srcDst)); stubCall.call(result); @@ -701,7 +1785,7 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction) emitGetVirtualRegister(srcDst, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) addSlowCase(branchAdd32(Overflow, Imm32(1), regT0)); emitFastArithIntToImmNoCheck(regT0, regT0); #else @@ -719,7 +1803,7 @@ void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEn linkSlowCase(iter); emitGetVirtualRegister(srcDst, regT0); notImm.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_pre_inc); + JITStubCall stubCall(this, cti_op_pre_inc); stubCall.addArgument(regT0); stubCall.call(srcDst); } @@ -730,7 +1814,7 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction) emitGetVirtualRegister(srcDst, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) addSlowCase(branchSub32(Zero, Imm32(1), regT0)); emitFastArithIntToImmNoCheck(regT0, regT0); #else @@ -748,7 +1832,7 @@ void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEn linkSlowCase(iter); emitGetVirtualRegister(srcDst, regT0); notImm.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_pre_dec); + JITStubCall stubCall(this, cti_op_pre_dec); stubCall.addArgument(regT0); stubCall.call(srcDst); } @@ -763,21 +1847,21 @@ void JIT::emit_op_mod(Instruction* currentInstruction) unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; - emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx); - emitJumpSlowCaseIfNotImmediateInteger(X86::eax); - emitJumpSlowCaseIfNotImmediateInteger(X86::ecx); -#if USE(ALTERNATE_JSIMMEDIATE) - addSlowCase(branchPtr(Equal, X86::ecx, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))))); + emitGetVirtualRegisters(op1, X86Registers::eax, op2, X86Registers::ecx); + emitJumpSlowCaseIfNotImmediateInteger(X86Registers::eax); + emitJumpSlowCaseIfNotImmediateInteger(X86Registers::ecx); +#if USE(JSVALUE64) + addSlowCase(branchPtr(Equal, X86Registers::ecx, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))))); m_assembler.cdq(); - m_assembler.idivl_r(X86::ecx); + m_assembler.idivl_r(X86Registers::ecx); #else - emitFastArithDeTagImmediate(X86::eax); - addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx)); + emitFastArithDeTagImmediate(X86Registers::eax); + addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86Registers::ecx)); m_assembler.cdq(); - m_assembler.idivl_r(X86::ecx); - signExtend32ToPtr(X86::edx, X86::edx); + m_assembler.idivl_r(X86Registers::ecx); + signExtend32ToPtr(X86Registers::edx, X86Registers::edx); #endif - emitFastArithReTagImmediate(X86::edx, X86::eax); + emitFastArithReTagImmediate(X86Registers::edx, X86Registers::eax); emitPutVirtualRegister(result); } @@ -785,7 +1869,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry> { unsigned result = currentInstruction[1].u.operand; -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) linkSlowCase(iter); linkSlowCase(iter); linkSlowCase(iter); @@ -793,14 +1877,14 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry> Jump notImm1 = getSlowCase(iter); Jump notImm2 = getSlowCase(iter); linkSlowCase(iter); - emitFastArithReTagImmediate(X86::eax, X86::eax); - emitFastArithReTagImmediate(X86::ecx, X86::ecx); + emitFastArithReTagImmediate(X86Registers::eax, X86Registers::eax); + emitFastArithReTagImmediate(X86Registers::ecx, X86Registers::ecx); notImm1.link(this); notImm2.link(this); #endif - JITStubCall stubCall(this, JITStubs::cti_op_mod); - stubCall.addArgument(X86::eax); - stubCall.addArgument(X86::ecx); + JITStubCall stubCall(this, cti_op_mod); + stubCall.addArgument(X86Registers::eax); + stubCall.addArgument(X86Registers::ecx); stubCall.call(result); } @@ -812,7 +1896,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; - JITStubCall stubCall(this, JITStubs::cti_op_mod); + JITStubCall stubCall(this, cti_op_mod); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -827,64 +1911,9 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&) /* ------------------------------ END: OP_MOD ------------------------------ */ -#if !ENABLE(JIT_OPTIMIZE_ARITHMETIC) - -/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_ARITHMETIC) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */ - -void JIT::emit_op_add(Instruction* currentInstruction) -{ - unsigned result = currentInstruction[1].u.operand; - unsigned op1 = currentInstruction[2].u.operand; - unsigned op2 = currentInstruction[3].u.operand; - - JITStubCall stubCall(this, JITStubs::cti_op_add); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); -} - -void JIT::emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&) -{ - ASSERT_NOT_REACHED(); -} - -void JIT::emit_op_mul(Instruction* currentInstruction) -{ - unsigned result = currentInstruction[1].u.operand; - unsigned op1 = currentInstruction[2].u.operand; - unsigned op2 = currentInstruction[3].u.operand; - - JITStubCall stubCall(this, JITStubs::cti_op_mul); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); -} - -void JIT::emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&) -{ - ASSERT_NOT_REACHED(); -} - -void JIT::emit_op_sub(Instruction* currentInstruction) -{ - unsigned result = currentInstruction[1].u.operand; - unsigned op1 = currentInstruction[2].u.operand; - unsigned op2 = currentInstruction[3].u.operand; +#if USE(JSVALUE64) - JITStubCall stubCall(this, JITStubs::cti_op_sub); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); -} - -void JIT::emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&) -{ - ASSERT_NOT_REACHED(); -} - -#elif USE(ALTERNATE_JSIMMEDIATE) // *AND* ENABLE(JIT_OPTIMIZE_ARITHMETIC) - -/* ------------------------------ BEGIN: USE(ALTERNATE_JSIMMEDIATE) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */ +/* ------------------------------ BEGIN: USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes) { @@ -917,7 +1946,7 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>: emitGetVirtualRegister(op1, regT0); Label stubFunctionCall(this); - JITStubCall stubCall(this, opcodeID == op_add ? JITStubs::cti_op_add : opcodeID == op_sub ? JITStubs::cti_op_sub : JITStubs::cti_op_mul); + JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(result); @@ -968,7 +1997,7 @@ void JIT::emit_op_add(Instruction* currentInstruction) OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { - JITStubCall stubCall(this, JITStubs::cti_op_add); + JITStubCall stubCall(this, cti_op_add); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1000,7 +2029,7 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry> if (isOperandConstantImmediateInt(op1) || isOperandConstantImmediateInt(op2)) { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_add); + JITStubCall stubCall(this, cti_op_add); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1045,7 +2074,7 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry> linkSlowCase(iter); linkSlowCase(iter); // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. - JITStubCall stubCall(this, JITStubs::cti_op_mul); + JITStubCall stubCall(this, cti_op_mul); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1075,9 +2104,9 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry> compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types); } -#else // !ENABLE(JIT_OPTIMIZE_ARITHMETIC) +#else // USE(JSVALUE64) -/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_ARITHMETIC) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */ +/* ------------------------------ BEGIN: !USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types) { @@ -1244,7 +2273,7 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>: if (opcodeID == op_mul) linkSlowCase(iter); - JITStubCall stubCall(this, opcodeID == op_add ? JITStubs::cti_op_add : opcodeID == op_sub ? JITStubs::cti_op_sub : JITStubs::cti_op_mul); + JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul); stubCall.addArgument(src1, regT2); stubCall.addArgument(src2, regT2); stubCall.call(dst); @@ -1273,7 +2302,7 @@ void JIT::emit_op_add(Instruction* currentInstruction) if (types.first().mightBeNumber() && types.second().mightBeNumber()) compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); else { - JITStubCall stubCall(this, JITStubs::cti_op_add); + JITStubCall stubCall(this, cti_op_add); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1292,7 +2321,7 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry> linkSlowCase(iter); sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0); notImm.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_add); + JITStubCall stubCall(this, cti_op_add); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(result); @@ -1301,7 +2330,7 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry> linkSlowCase(iter); sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0); notImm.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_add); + JITStubCall stubCall(this, cti_op_add); stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1351,7 +2380,7 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry> linkSlowCase(iter); linkSlowCase(iter); // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. - JITStubCall stubCall(this, JITStubs::cti_op_mul); + JITStubCall stubCall(this, cti_op_mul); stubCall.addArgument(op1, regT2); stubCall.addArgument(op2, regT2); stubCall.call(result); @@ -1369,10 +2398,12 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry> compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand)); } -#endif // !ENABLE(JIT_OPTIMIZE_ARITHMETIC) +#endif // USE(JSVALUE64) /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */ +#endif // USE(JSVALUE32_64) + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp index abdb5ed..5bcde42 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp @@ -45,14 +45,407 @@ using namespace std; namespace JSC { +#if USE(JSVALUE32_64) + +void JIT::compileOpCallInitializeCallFrame() +{ + // regT0 holds callee, regT1 holds argCount + store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); + + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // scopeChain + + emitStore(static_cast<unsigned>(RegisterFile::OptionalCalleeArguments), JSValue()); + storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); // callee + storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); // scopeChain +} + +void JIT::compileOpCallSetupArgs(Instruction* instruction) +{ + int argCount = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + + emitPutJITStubArg(regT1, regT0, 0); + emitPutJITStubArgConstant(registerOffset, 1); + emitPutJITStubArgConstant(argCount, 2); +} + +void JIT::compileOpConstructSetupArgs(Instruction* instruction) +{ + int argCount = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + int proto = instruction[5].u.operand; + int thisRegister = instruction[6].u.operand; + + emitPutJITStubArg(regT1, regT0, 0); + emitPutJITStubArgConstant(registerOffset, 1); + emitPutJITStubArgConstant(argCount, 2); + emitPutJITStubArgFromVirtualRegister(proto, 3, regT2, regT3); + emitPutJITStubArgConstant(thisRegister, 4); +} + +void JIT::compileOpCallVarargsSetupArgs(Instruction*) +{ + emitPutJITStubArg(regT1, regT0, 0); + emitPutJITStubArg(regT3, 1); // registerOffset + emitPutJITStubArg(regT2, 2); // argCount +} + +void JIT::compileOpCallVarargs(Instruction* instruction) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + int argCountRegister = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + + emitLoad(callee, regT1, regT0); + emitLoadPayload(argCountRegister, regT2); // argCount + addPtr(Imm32(registerOffset), regT2, regT3); // registerOffset + + compileOpCallVarargsSetupArgs(instruction); + + emitJumpSlowCaseIfNotJSCell(callee, regT1); + addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); + + // Speculatively roll the callframe, assuming argCount will match the arity. + mul32(Imm32(sizeof(Register)), regT3, regT3); + addPtr(callFrameRegister, regT3); + storePtr(callFrameRegister, Address(regT3, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register)))); + move(regT3, callFrameRegister); + + move(regT2, regT1); // argCount + + emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); + + emitStore(dst, regT1, regT0); + + sampleCodeBlock(m_codeBlock); +} + +void JIT::compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + + linkSlowCaseIfNotJSCell(iter, callee); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_call_NotJSFunction); + stubCall.call(dst); // In the interpreter, the callee puts the return value in dst. + + map(m_bytecodeIndex + OPCODE_LENGTH(op_call_varargs), dst, regT1, regT0); + sampleCodeBlock(m_codeBlock); +} + +void JIT::emit_op_ret(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + +#ifdef QT_BUILD_SCRIPT_LIB + JITStubCall stubCall(this, cti_op_debug_return); + stubCall.addArgument(Imm32(dst)); + stubCall.call(); +#endif + + // We could JIT generate the deref, only calling out to C when the refcount hits zero. + if (m_codeBlock->needsFullScopeChain()) + JITStubCall(this, cti_op_ret_scopeChain).call(); + + emitLoad(dst, regT1, regT0); + emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2); + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + + restoreReturnAddressBeforeReturn(regT2); + ret(); +} + +void JIT::emit_op_construct_verify(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + + emitLoad(dst, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + addSlowCase(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType))); +} + +void JIT::emitSlow_op_construct_verify(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + linkSlowCase(iter); + linkSlowCase(iter); + emitLoad(src, regT1, regT0); + emitStore(dst, regT1, regT0); +} + +void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call); +} + +void JIT::emitSlow_op_call_eval(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call_eval); +} + +void JIT::emitSlow_op_call_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + compileOpCallVarargsSlowCase(currentInstruction, iter); +} + +void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_construct); +} + +void JIT::emit_op_call(Instruction* currentInstruction) +{ + compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++); +} + +void JIT::emit_op_call_eval(Instruction* currentInstruction) +{ + compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++); +} + +void JIT::emit_op_load_varargs(Instruction* currentInstruction) +{ + int argCountDst = currentInstruction[1].u.operand; + int argsOffset = currentInstruction[2].u.operand; + + JITStubCall stubCall(this, cti_op_load_varargs); + stubCall.addArgument(Imm32(argsOffset)); + stubCall.call(); + // Stores a naked int32 in the register file. + store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register))); +} + +void JIT::emit_op_call_varargs(Instruction* currentInstruction) +{ + compileOpCallVarargs(currentInstruction); +} + +void JIT::emit_op_construct(Instruction* currentInstruction) +{ + compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++); +} + +#if !ENABLE(JIT_OPTIMIZE_CALL) + +/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */ + +void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + int argCount = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + + Jump wasEval1; + Jump wasEval2; + 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)); + } + + emitLoad(callee, regT1, regT2); + + if (opcodeID == op_call) + compileOpCallSetupArgs(instruction); + else if (opcodeID == op_construct) + compileOpConstructSetupArgs(instruction); + + emitJumpSlowCaseIfNotJSCell(callee, regT1); + addSlowCase(branchPtr(NotEqual, Address(regT2), 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); + } + + // Speculatively roll the callframe, assuming argCount will match the arity. + storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)))); + addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); + move(Imm32(argCount), regT1); + + emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); + + if (opcodeID == op_call_eval) { + wasEval1.link(this); + wasEval2.link(this); + } + + emitStore(dst, regT1, regT0);; + + sampleCodeBlock(m_codeBlock); +} + +void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned, OpcodeID opcodeID) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + + linkSlowCaseIfNotJSCell(iter, callee); + linkSlowCase(iter); + + JITStubCall stubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction); + stubCall.call(dst); // In the interpreter, the callee puts the return value in dst. + + sampleCodeBlock(m_codeBlock); +} + +#else // !ENABLE(JIT_OPTIMIZE_CALL) + +/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */ + +void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + int argCount = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + + Jump wasEval1; + Jump wasEval2; + 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)); + } + + emitLoad(callee, regT1, regT0); + + DataLabelPtr addressOfLinkedFunctionCheck; + Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(0)); + addSlowCase(jumpToSlow); + ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump); + m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; + + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); + + // The following is the fast case, only used whan a callee can be linked. + + // In the case of OpConstruct, call out to a cti_ function to create the new object. + if (opcodeID == op_construct) { + int proto = instruction[5].u.operand; + int thisRegister = instruction[6].u.operand; + + JITStubCall stubCall(this, cti_op_construct_JSConstruct); + stubCall.addArgument(regT1, regT0); + stubCall.addArgument(Imm32(0)); // FIXME: Remove this unused JITStub argument. + stubCall.addArgument(Imm32(0)); // FIXME: Remove this unused JITStub argument. + stubCall.addArgument(proto); + stubCall.call(thisRegister); + + emitLoad(callee, regT1, regT0); + } + + // Fast version of stack frame initialization, directly relative to edi. + // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee + emitStore(registerOffset + RegisterFile::OptionalCalleeArguments, JSValue()); + emitStore(registerOffset + RegisterFile::Callee, regT1, regT0); + + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain + store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); + storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); + storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register)))); + addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister); + + // Call to the callee + m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); + + if (opcodeID == op_call_eval) { + wasEval1.link(this); + wasEval2.link(this); + } + + // Put the return value in dst. In the interpreter, op_ret does this. + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + opcodeLengths[opcodeID], dst, regT1, regT0); + + sampleCodeBlock(m_codeBlock); +} + +void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID) +{ + int dst = instruction[1].u.operand; + int callee = instruction[2].u.operand; + int argCount = instruction[3].u.operand; + int registerOffset = instruction[4].u.operand; + + linkSlowCase(iter); + linkSlowCase(iter); + + // The arguments have been set up on the hot path for op_call_eval + if (opcodeID == op_call) + compileOpCallSetupArgs(instruction); + else if (opcodeID == op_construct) + compileOpConstructSetupArgs(instruction); + + // Fast check for JS function. + Jump callLinkFailNotObject = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + Jump callLinkFailNotJSFunction = 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, regT0); + } + + // Speculatively roll the callframe, assuming argCount will match the arity. + storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)))); + addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); + move(Imm32(argCount), regT1); + + m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink()); + + // Put the return value in dst. + emitStore(dst, regT1, regT0);; + sampleCodeBlock(m_codeBlock); + + // If not, we need an extra case in the if below! + ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval)); + + // Done! - return back to the hot path. + if (opcodeID == op_construct) + emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_construct)); + else + emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_call)); + + // This handles host functions + callLinkFailNotObject.link(this); + callLinkFailNotJSFunction.link(this); + JITStubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction).call(); + + emitStore(dst, regT1, regT0);; + sampleCodeBlock(m_codeBlock); +} + +/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */ + +#endif // !ENABLE(JIT_OPTIMIZE_CALL) + +#else // USE(JSVALUE32_64) + void JIT::compileOpCallInitializeCallFrame() { store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)))); - storePtr(regT2, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); + storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); } @@ -62,9 +455,9 @@ void JIT::compileOpCallSetupArgs(Instruction* instruction) int registerOffset = instruction[4].u.operand; // ecx holds func - emitPutJITStubArg(regT2, 1); - emitPutJITStubArgConstant(argCount, 3); - emitPutJITStubArgConstant(registerOffset, 2); + emitPutJITStubArg(regT0, 0); + emitPutJITStubArgConstant(argCount, 2); + emitPutJITStubArgConstant(registerOffset, 1); } void JIT::compileOpCallVarargsSetupArgs(Instruction* instruction) @@ -72,10 +465,10 @@ void JIT::compileOpCallVarargsSetupArgs(Instruction* instruction) int registerOffset = instruction[4].u.operand; // ecx holds func + emitPutJITStubArg(regT0, 0); + emitPutJITStubArg(regT1, 2); + addPtr(Imm32(registerOffset), regT1, regT2); emitPutJITStubArg(regT2, 1); - emitPutJITStubArg(regT1, 3); - addPtr(Imm32(registerOffset), regT1, regT0); - emitPutJITStubArg(regT0, 2); } void JIT::compileOpConstructSetupArgs(Instruction* instruction) @@ -86,11 +479,11 @@ void JIT::compileOpConstructSetupArgs(Instruction* instruction) int thisRegister = instruction[6].u.operand; // ecx holds func - emitPutJITStubArg(regT2, 1); - emitPutJITStubArgConstant(registerOffset, 2); - emitPutJITStubArgConstant(argCount, 3); - emitPutJITStubArgFromVirtualRegister(proto, 4, regT0); - emitPutJITStubArgConstant(thisRegister, 5); + emitPutJITStubArg(regT0, 0); + emitPutJITStubArgConstant(registerOffset, 1); + emitPutJITStubArgConstant(argCount, 2); + emitPutJITStubArgFromVirtualRegister(proto, 3, regT2); + emitPutJITStubArgConstant(thisRegister, 4); } void JIT::compileOpCallVarargs(Instruction* instruction) @@ -100,20 +493,20 @@ void JIT::compileOpCallVarargs(Instruction* instruction) int argCountRegister = instruction[3].u.operand; emitGetVirtualRegister(argCountRegister, regT1); - emitGetVirtualRegister(callee, regT2); + emitGetVirtualRegister(callee, regT0); compileOpCallVarargsSetupArgs(instruction); // Check for JSFunctions. - emitJumpSlowCaseIfNotJSCell(regT2); - addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr))); - + emitJumpSlowCaseIfNotJSCell(regT0); + addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); + // Speculatively roll the callframe, assuming argCount will match the arity. - mul32(Imm32(sizeof(Register)), regT0, regT0); + mul32(Imm32(sizeof(Register)), regT2, regT2); intptr_t offset = (intptr_t)sizeof(Register) * (intptr_t)RegisterFile::CallerFrame; - addPtr(Imm32((int32_t)offset), regT0, regT3); + addPtr(Imm32((int32_t)offset), regT2, regT3); addPtr(callFrameRegister, regT3); storePtr(callFrameRegister, regT3); - addPtr(regT0, callFrameRegister); + addPtr(regT2, callFrameRegister); emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); // Put the return value in dst. In the interpreter, op_ret does this. @@ -128,7 +521,7 @@ void JIT::compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCase linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_call_NotJSFunction); + JITStubCall stubCall(this, cti_op_call_NotJSFunction); stubCall.call(dst); // In the interpreter, the callee puts the return value in dst. sampleCodeBlock(m_codeBlock); @@ -148,11 +541,15 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) // Handle eval Jump wasEval; if (opcodeID == op_call_eval) { - CallEvalJITStub(this, instruction).call(); + JITStubCall stubCall(this, cti_op_call_eval); + stubCall.addArgument(callee, regT0); + stubCall.addArgument(JIT::Imm32(registerOffset)); + stubCall.addArgument(JIT::Imm32(argCount)); + stubCall.call(); wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue()))); } - emitGetVirtualRegister(callee, regT2); + emitGetVirtualRegister(callee, regT0); // The arguments have been set up on the hot path for op_call_eval if (opcodeID == op_call) compileOpCallSetupArgs(instruction); @@ -160,13 +557,13 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) compileOpConstructSetupArgs(instruction); // Check for JSFunctions. - emitJumpSlowCaseIfNotJSCell(regT2); - addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr))); + emitJumpSlowCaseIfNotJSCell(regT0); + 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, JITStubs::cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); - emitGetVirtualRegister(callee, regT2); + JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); + emitGetVirtualRegister(callee, regT0); } // Speculatively roll the callframe, assuming argCount will match the arity. @@ -191,7 +588,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>: linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, opcodeID == op_construct ? JITStubs::cti_op_construct_NotJSConstruct : JITStubs::cti_op_call_NotJSFunction); + JITStubCall stubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction); stubCall.call(dst); // In the interpreter, the callee puts the return value in dst. sampleCodeBlock(m_codeBlock); @@ -211,15 +608,25 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Handle eval Jump wasEval; if (opcodeID == op_call_eval) { - CallEvalJITStub(this, instruction).call(); + JITStubCall stubCall(this, cti_op_call_eval); + stubCall.addArgument(callee, regT0); + stubCall.addArgument(JIT::Imm32(registerOffset)); + stubCall.addArgument(JIT::Imm32(argCount)); + stubCall.call(); wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue()))); } // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee. // This deliberately leaves the callee in ecx, used when setting up the stack frame below - emitGetVirtualRegister(callee, regT2); + emitGetVirtualRegister(callee, regT0); DataLabelPtr addressOfLinkedFunctionCheck; - Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT2, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue()))); + + BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall); + + Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue()))); + + END_UNINTERRUPTED_SEQUENCE(sequenceOpCall); + addSlowCase(jumpToSlow); ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; @@ -231,18 +638,18 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca int proto = instruction[5].u.operand; int thisRegister = instruction[6].u.operand; - emitPutJITStubArg(regT2, 1); - emitPutJITStubArgFromVirtualRegister(proto, 4, regT0); - JITStubCall stubCall(this, JITStubs::cti_op_construct_JSConstruct); + emitPutJITStubArg(regT0, 0); + emitPutJITStubArgFromVirtualRegister(proto, 3, regT2); + JITStubCall stubCall(this, cti_op_construct_JSConstruct); stubCall.call(thisRegister); - emitGetVirtualRegister(callee, regT2); + emitGetVirtualRegister(callee, regT0); } // Fast version of stack frame initialization, directly relative to edi. // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)))); - storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)))); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain + storePtr(regT0, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)))); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register)))); @@ -276,13 +683,13 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>: compileOpConstructSetupArgs(instruction); // Fast check for JS function. - Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2); - Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)); + Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT0); + Jump callLinkFailNotJSFunction = 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, JITStubs::cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); - emitGetVirtualRegister(callee, regT2); + JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); + emitGetVirtualRegister(callee, regT0); } // Speculatively roll the callframe, assuming argCount will match the arity. @@ -290,7 +697,9 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>: addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); move(Imm32(argCount), regT1); - m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink()); + move(regT0, regT2); + + m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink()); // Put the return value in dst. emitPutVirtualRegister(dst); @@ -308,7 +717,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>: // This handles host functions callLinkFailNotObject.link(this); callLinkFailNotJSFunction.link(this); - JITStubCall(this, opcodeID == op_construct ? JITStubs::cti_op_construct_NotJSConstruct : JITStubs::cti_op_call_NotJSFunction).call(); + JITStubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction).call(); emitPutVirtualRegister(dst); sampleCodeBlock(m_codeBlock); @@ -318,6 +727,8 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>: #endif // !ENABLE(JIT_OPTIMIZE_CALL) +#endif // USE(JSVALUE32_64) + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCode.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCode.h index b502c8a..69cf167 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCode.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCode.h @@ -76,11 +76,7 @@ namespace JSC { // Execute the code! inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValue* exception) { - return JSValue::decode(ctiTrampoline( -#if PLATFORM(X86_64) - 0, 0, 0, 0, 0, 0, -#endif - m_ref.m_code.executableAddress(), registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData)); + return JSValue::decode(ctiTrampoline(m_ref.m_code.executableAddress(), registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData)); } void* start() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h index f03d635..e69e273 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h @@ -32,75 +32,37 @@ namespace JSC { -ALWAYS_INLINE void JIT::killLastResultRegister() -{ - m_lastResultBytecodeRegister = std::numeric_limits<int>::max(); -} - -// get arg puts an arg from the SF register array into a h/w register -ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst) -{ - ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. - - // TODO: we want to reuse values that are already in registers if we can - add a register allocator! - if (m_codeBlock->isConstantRegisterIndex(src)) { - JSValue value = m_codeBlock->getConstant(src); - move(ImmPtr(JSValue::encode(value)), dst); - killLastResultRegister(); - return; - } - - if (src == m_lastResultBytecodeRegister && m_codeBlock->isTemporaryRegisterIndex(src)) { - bool atJumpTarget = false; - while (m_jumpTargetsPosition < m_codeBlock->numberOfJumpTargets() && m_codeBlock->jumpTarget(m_jumpTargetsPosition) <= m_bytecodeIndex) { - if (m_codeBlock->jumpTarget(m_jumpTargetsPosition) == m_bytecodeIndex) - atJumpTarget = true; - ++m_jumpTargetsPosition; - } - - if (!atJumpTarget) { - // The argument we want is already stored in eax - if (dst != cachedResultRegister) - move(cachedResultRegister, dst); - killLastResultRegister(); - return; - } - } - - loadPtr(Address(callFrameRegister, src * sizeof(Register)), dst); - killLastResultRegister(); -} - -ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2) -{ - if (src2 == m_lastResultBytecodeRegister) { - emitGetVirtualRegister(src2, dst2); - emitGetVirtualRegister(src1, dst1); - } else { - emitGetVirtualRegister(src1, dst1); - emitGetVirtualRegister(src2, dst2); - } -} +/* Deprecated: Please use JITStubCall instead. */ // puts an arg onto the stack, as an arg to a context threaded function. ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumber) { - poke(src, argumentNumber); + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + poke(src, argumentStackOffset); } +/* Deprecated: Please use JITStubCall instead. */ + ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber) { - poke(Imm32(value), argumentNumber); + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + poke(Imm32(value), argumentStackOffset); } +/* Deprecated: Please use JITStubCall instead. */ + ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argumentNumber) { - poke(ImmPtr(value), argumentNumber); + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + poke(ImmPtr(value), argumentStackOffset); } +/* Deprecated: Please use JITStubCall instead. */ + ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID dst) { - peek(dst, argumentNumber); + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + peek(dst, argumentStackOffset); } ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src) @@ -109,30 +71,6 @@ ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src) return m_codeBlock->getConstant(src); } -ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src) -{ - return getConstantOperand(src).getInt32Fast(); -} - -ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src) -{ - return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32Fast(); -} - -// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function. -ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch) -{ - if (m_codeBlock->isConstantRegisterIndex(src)) { - JSValue value = m_codeBlock->getConstant(src); - emitPutJITStubArgConstant(JSValue::encode(value), argumentNumber); - } else { - loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch); - emitPutJITStubArg(scratch, argumentNumber); - } - - killLastResultRegister(); -} - ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry) { storePtr(from, Address(callFrameRegister, entry * sizeof(Register))); @@ -146,26 +84,17 @@ ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterF ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) { loadPtr(Address(from, entry * sizeof(Register)), to); +#if !USE(JSVALUE32_64) killLastResultRegister(); +#endif } ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) { load32(Address(from, entry * sizeof(Register)), to); +#if !USE(JSVALUE32_64) killLastResultRegister(); -} - -ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from) -{ - storePtr(from, Address(callFrameRegister, dst * sizeof(Register))); - m_lastResultBytecodeRegister = (from == cachedResultRegister) ? dst : std::numeric_limits<int>::max(); - // FIXME: #ifndef NDEBUG, Write the correct m_type to the register. -} - -ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst) -{ - storePtr(ImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register))); - // FIXME: #ifndef NDEBUG, Write the correct m_type to the register. +#endif } ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function) @@ -177,38 +106,71 @@ ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function) return nakedCall; } -#if PLATFORM(X86) || PLATFORM(X86_64) +#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL + +ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace) +{ +#if PLATFORM(ARM_TRADITIONAL) +#ifndef NDEBUG + // Ensure the label after the sequence can also fit + insnSpace += sizeof(ARMWord); + constSpace += sizeof(uint64_t); +#endif + + ensureSpace(insnSpace, constSpace); + +#endif + +#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL +#ifndef NDEBUG + m_uninterruptedInstructionSequenceBegin = label(); + m_uninterruptedConstantSequenceBegin = sizeOfConstantPool(); +#endif +#endif +} + +ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) +{ +#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL + ASSERT(differenceBetween(m_uninterruptedInstructionSequenceBegin, label()) == insnSpace); + ASSERT(sizeOfConstantPool() - m_uninterruptedConstantSequenceBegin == constSpace); +#endif +} + +#endif + +#if PLATFORM(ARM_THUMB2) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { - pop(reg); + move(linkRegister, reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg) { - push(reg); + move(reg, linkRegister); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) { - push(address); + loadPtr(address, linkRegister); } -#elif PLATFORM_ARM_ARCH(7) +#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { - move(linkRegister, reg); + pop(reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg) { - move(reg, linkRegister); + push(reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) { - loadPtr(address, linkRegister); + push(address); } #endif @@ -224,13 +186,16 @@ 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_ARCH(7) +#elif PLATFORM(ARM_THUMB2) move(stackPointerRegister, firstArgumentRegister); #endif // In the trampoline on x86-64, the first argument register is not overwritten. @@ -242,9 +207,484 @@ ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure return branchPtr(NotEqual, Address(reg, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(structure)); } +ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg) +{ + if (!m_codeBlock->isKnownNotImmediate(vReg)) + linkSlowCase(iter); +} + +ALWAYS_INLINE void JIT::addSlowCase(Jump jump) +{ + ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. + + m_slowCases.append(SlowCaseEntry(jump, m_bytecodeIndex)); +} + +ALWAYS_INLINE void JIT::addSlowCase(JumpList jumpList) +{ + ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. + + const JumpList::JumpVector& jumpVector = jumpList.jumps(); + size_t size = jumpVector.size(); + for (size_t i = 0; i < size; ++i) + m_slowCases.append(SlowCaseEntry(jumpVector[i], m_bytecodeIndex)); +} + +ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset) +{ + ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. + + m_jmpTable.append(JumpTable(jump, m_bytecodeIndex + relativeOffset)); +} + +ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset) +{ + ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. + + jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this); +} + +#if ENABLE(SAMPLING_FLAGS) +ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag) +{ + ASSERT(flag >= 1); + ASSERT(flag <= 32); + or32(Imm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags)); +} + +ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag) +{ + ASSERT(flag >= 1); + ASSERT(flag <= 32); + and32(Imm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags)); +} +#endif + +#if ENABLE(SAMPLING_COUNTERS) +ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count) +{ +#if PLATFORM(X86_64) // Or any other 64-bit plattform. + addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter)); +#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform. + intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t); + add32(Imm32(count), AbsoluteAddress(&counter.m_counter)); + addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord))); +#else +#error "SAMPLING_FLAGS not implemented on this platform." +#endif +} +#endif + +#if ENABLE(OPCODE_SAMPLING) +#if PLATFORM(X86_64) +ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction) +{ + move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx); + storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86Registers::ecx); +} +#else +ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction) +{ + storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot()); +} +#endif +#endif + +#if ENABLE(CODEBLOCK_SAMPLING) +#if PLATFORM(X86_64) +ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) +{ + move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx); + storePtr(ImmPtr(codeBlock), X86Registers::ecx); +} +#else +ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) +{ + storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot()); +} +#endif +#endif + +#if USE(JSVALUE32_64) + +inline JIT::Address JIT::tagFor(unsigned index, RegisterID base) +{ + return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); +} + +inline JIT::Address JIT::payloadFor(unsigned index, RegisterID base) +{ + return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); +} + +inline JIT::Address JIT::addressFor(unsigned index, RegisterID base) +{ + return Address(base, (index * sizeof(Register))); +} + +inline void JIT::emitLoadTag(unsigned index, RegisterID tag) +{ + RegisterID mappedTag; + if (getMappedTag(index, mappedTag)) { + move(mappedTag, tag); + unmap(tag); + return; + } + + if (m_codeBlock->isConstantRegisterIndex(index)) { + move(Imm32(getConstantOperand(index).tag()), tag); + unmap(tag); + return; + } + + load32(tagFor(index), tag); + unmap(tag); +} + +inline void JIT::emitLoadPayload(unsigned index, RegisterID payload) +{ + RegisterID mappedPayload; + if (getMappedPayload(index, mappedPayload)) { + move(mappedPayload, payload); + unmap(payload); + return; + } + + if (m_codeBlock->isConstantRegisterIndex(index)) { + move(Imm32(getConstantOperand(index).payload()), payload); + unmap(payload); + return; + } + + load32(payloadFor(index), payload); + unmap(payload); +} + +inline void JIT::emitLoad(const JSValue& v, RegisterID tag, RegisterID payload) +{ + move(Imm32(v.payload()), payload); + move(Imm32(v.tag()), tag); +} + +inline void JIT::emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base) +{ + ASSERT(tag != payload); + + if (base == callFrameRegister) { + ASSERT(payload != base); + emitLoadPayload(index, payload); + emitLoadTag(index, tag); + return; + } + + if (payload == base) { // avoid stomping base + load32(tagFor(index, base), tag); + load32(payloadFor(index, base), payload); + return; + } + + load32(payloadFor(index, base), payload); + load32(tagFor(index, base), tag); +} + +inline void JIT::emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2) +{ + if (isMapped(index1)) { + emitLoad(index1, tag1, payload1); + emitLoad(index2, tag2, payload2); + return; + } + emitLoad(index2, tag2, payload2); + emitLoad(index1, tag1, payload1); +} + +inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value) +{ + if (m_codeBlock->isConstantRegisterIndex(index)) { + Register& inConstantPool = m_codeBlock->constantRegister(index); + loadDouble(&inConstantPool, value); + } else + loadDouble(addressFor(index), value); +} + +inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value) +{ + if (m_codeBlock->isConstantRegisterIndex(index)) { + Register& inConstantPool = m_codeBlock->constantRegister(index); + char* bytePointer = reinterpret_cast<char*>(&inConstantPool); + convertInt32ToDouble(AbsoluteAddress(bytePointer + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), value); + } else + convertInt32ToDouble(payloadFor(index), value); +} + +inline void JIT::emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base) +{ + store32(payload, payloadFor(index, base)); + store32(tag, tagFor(index, base)); +} + +inline void JIT::emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32) +{ + store32(payload, payloadFor(index, callFrameRegister)); + if (!indexIsInt32) + store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister)); +} + +inline void JIT::emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32) +{ + store32(payload, payloadFor(index, callFrameRegister)); + if (!indexIsInt32) + store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister)); +} + +inline void JIT::emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell) +{ + store32(payload, payloadFor(index, callFrameRegister)); + if (!indexIsCell) + store32(Imm32(JSValue::CellTag), tagFor(index, callFrameRegister)); +} + +inline void JIT::emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool) +{ + if (!indexIsBool) + store32(Imm32(0), payloadFor(index, callFrameRegister)); + store32(tag, tagFor(index, callFrameRegister)); +} + +inline void JIT::emitStoreDouble(unsigned index, FPRegisterID value) +{ + storeDouble(value, addressFor(index)); +} + +inline void JIT::emitStore(unsigned index, const JSValue constant, RegisterID base) +{ + store32(Imm32(constant.payload()), payloadFor(index, base)); + store32(Imm32(constant.tag()), tagFor(index, base)); +} + +ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst) +{ + emitStore(dst, jsUndefined()); +} + +inline bool JIT::isLabeled(unsigned bytecodeIndex) +{ + for (size_t numberOfJumpTargets = m_codeBlock->numberOfJumpTargets(); m_jumpTargetIndex != numberOfJumpTargets; ++m_jumpTargetIndex) { + unsigned jumpTarget = m_codeBlock->jumpTarget(m_jumpTargetIndex); + if (jumpTarget == bytecodeIndex) + return true; + if (jumpTarget > bytecodeIndex) + return false; + } + return false; +} + +inline void JIT::map(unsigned bytecodeIndex, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload) +{ + if (isLabeled(bytecodeIndex)) + return; + + m_mappedBytecodeIndex = bytecodeIndex; + m_mappedVirtualRegisterIndex = virtualRegisterIndex; + m_mappedTag = tag; + m_mappedPayload = payload; +} + +inline void JIT::unmap(RegisterID registerID) +{ + if (m_mappedTag == registerID) + m_mappedTag = (RegisterID)-1; + else if (m_mappedPayload == registerID) + m_mappedPayload = (RegisterID)-1; +} + +inline void JIT::unmap() +{ + m_mappedBytecodeIndex = (unsigned)-1; + m_mappedVirtualRegisterIndex = (unsigned)-1; + m_mappedTag = (RegisterID)-1; + m_mappedPayload = (RegisterID)-1; +} + +inline bool JIT::isMapped(unsigned virtualRegisterIndex) +{ + if (m_mappedBytecodeIndex != m_bytecodeIndex) + return false; + if (m_mappedVirtualRegisterIndex != virtualRegisterIndex) + return false; + return true; +} + +inline bool JIT::getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload) +{ + if (m_mappedBytecodeIndex != m_bytecodeIndex) + return false; + if (m_mappedVirtualRegisterIndex != virtualRegisterIndex) + return false; + if (m_mappedPayload == (RegisterID)-1) + return false; + payload = m_mappedPayload; + return true; +} + +inline bool JIT::getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag) +{ + if (m_mappedBytecodeIndex != m_bytecodeIndex) + return false; + if (m_mappedVirtualRegisterIndex != virtualRegisterIndex) + return false; + if (m_mappedTag == (RegisterID)-1) + return false; + tag = m_mappedTag; + return true; +} + +inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex) +{ + if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) + addSlowCase(branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::CellTag))); +} + +inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag) +{ + if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) + addSlowCase(branch32(NotEqual, tag, Imm32(JSValue::CellTag))); +} + +inline void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, unsigned virtualRegisterIndex) +{ + if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) + linkSlowCase(iter); +} + +ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src) +{ + return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32(); +} + +ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant) +{ + if (isOperandConstantImmediateInt(op1)) { + constant = getConstantOperand(op1).asInt32(); + op = op2; + return true; + } + + if (isOperandConstantImmediateInt(op2)) { + constant = getConstantOperand(op2).asInt32(); + op = op1; + return true; + } + + return false; +} + +ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src) +{ + return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble(); +} + +/* Deprecated: Please use JITStubCall instead. */ + +ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber) +{ + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + poke(payload, argumentStackOffset); + poke(tag, argumentStackOffset + 1); +} + +/* Deprecated: Please use JITStubCall instead. */ + +ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2) +{ + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + if (m_codeBlock->isConstantRegisterIndex(src)) { + JSValue constant = m_codeBlock->getConstant(src); + poke(Imm32(constant.payload()), argumentStackOffset); + poke(Imm32(constant.tag()), argumentStackOffset + 1); + } else { + emitLoad(src, scratch1, scratch2); + poke(scratch2, argumentStackOffset); + poke(scratch1, argumentStackOffset + 1); + } +} + +#else // USE(JSVALUE32_64) + +ALWAYS_INLINE void JIT::killLastResultRegister() +{ + m_lastResultBytecodeRegister = std::numeric_limits<int>::max(); +} + +// get arg puts an arg from the SF register array into a h/w register +ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst) +{ + ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. + + // TODO: we want to reuse values that are already in registers if we can - add a register allocator! + if (m_codeBlock->isConstantRegisterIndex(src)) { + JSValue value = m_codeBlock->getConstant(src); + move(ImmPtr(JSValue::encode(value)), dst); + killLastResultRegister(); + return; + } + + if (src == m_lastResultBytecodeRegister && m_codeBlock->isTemporaryRegisterIndex(src)) { + bool atJumpTarget = false; + while (m_jumpTargetsPosition < m_codeBlock->numberOfJumpTargets() && m_codeBlock->jumpTarget(m_jumpTargetsPosition) <= m_bytecodeIndex) { + if (m_codeBlock->jumpTarget(m_jumpTargetsPosition) == m_bytecodeIndex) + atJumpTarget = true; + ++m_jumpTargetsPosition; + } + + if (!atJumpTarget) { + // The argument we want is already stored in eax + if (dst != cachedResultRegister) + move(cachedResultRegister, dst); + killLastResultRegister(); + return; + } + } + + loadPtr(Address(callFrameRegister, src * sizeof(Register)), dst); + killLastResultRegister(); +} + +ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2) +{ + if (src2 == m_lastResultBytecodeRegister) { + emitGetVirtualRegister(src2, dst2); + emitGetVirtualRegister(src1, dst1); + } else { + emitGetVirtualRegister(src1, dst1); + emitGetVirtualRegister(src2, dst2); + } +} + +ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src) +{ + return getConstantOperand(src).asInt32(); +} + +ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src) +{ + return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32(); +} + +ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from) +{ + storePtr(from, Address(callFrameRegister, dst * sizeof(Register))); + m_lastResultBytecodeRegister = (from == cachedResultRegister) ? dst : std::numeric_limits<int>::max(); +} + +ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst) +{ + storePtr(ImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register))); +} + ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return branchTestPtr(Zero, reg, tagMaskRegister); #else return branchTest32(Zero, reg, Imm32(JSImmediate::TagMask)); @@ -265,7 +705,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg) ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return branchTestPtr(NonZero, reg, tagMaskRegister); #else return branchTest32(NonZero, reg, Imm32(JSImmediate::TagMask)); @@ -283,13 +723,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg) emitJumpSlowCaseIfNotJSCell(reg); } -ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg) -{ - if (!m_codeBlock->isKnownNotImmediate(vReg)) - linkSlowCase(iter); -} - -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateNumber(RegisterID reg) { return branchTestPtr(NonZero, reg, tagTypeNumberRegister); @@ -302,7 +736,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg) ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return branchPtr(AboveOrEqual, reg, tagTypeNumberRegister); #else return branchTest32(NonZero, reg, Imm32(JSImmediate::TagTypeNumber)); @@ -311,7 +745,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg) ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return branchPtr(Below, reg, tagTypeNumberRegister); #else return branchTest32(Zero, reg, Imm32(JSImmediate::TagTypeNumber)); @@ -335,7 +769,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1, addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch)); } -#if !USE(ALTERNATE_JSIMMEDIATE) +#if !USE(JSVALUE64) ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg) { subPtr(Imm32(JSImmediate::TagTypeNumber), reg); @@ -349,7 +783,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID re ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID dest) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) emitFastArithIntToImmNoCheck(src, dest); #else if (src != dest) @@ -360,7 +794,7 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) UNUSED_PARAM(reg); #else rshiftPtr(Imm32(JSImmediate::IntegerPayloadShift), reg); @@ -370,7 +804,7 @@ ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg) // operand is int32_t, must have been zero-extended if register is 64-bit. ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) if (src != dest) move(src, dest); orPtr(tagTypeNumberRegister, dest); @@ -387,88 +821,26 @@ ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg) or32(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg); } -ALWAYS_INLINE void JIT::addSlowCase(Jump jump) -{ - ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. +/* Deprecated: Please use JITStubCall instead. */ - m_slowCases.append(SlowCaseEntry(jump, m_bytecodeIndex)); -} - -ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset) -{ - ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. - - m_jmpTable.append(JumpTable(jump, m_bytecodeIndex + relativeOffset)); -} - -ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset) -{ - ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set. - - jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this); -} - -#if ENABLE(SAMPLING_FLAGS) -ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag) -{ - ASSERT(flag >= 1); - ASSERT(flag <= 32); - or32(Imm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags)); -} - -ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag) +// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function. +ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch) { - ASSERT(flag >= 1); - ASSERT(flag <= 32); - and32(Imm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags)); -} -#endif + unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1; + if (m_codeBlock->isConstantRegisterIndex(src)) { + JSValue value = m_codeBlock->getConstant(src); + poke(ImmPtr(JSValue::encode(value)), argumentStackOffset); + } else { + loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch); + poke(scratch, argumentStackOffset); + } -#if ENABLE(SAMPLING_COUNTERS) -ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count) -{ -#if PLATFORM(X86_64) // Or any other 64-bit plattform. - addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter)); -#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform. - intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t); - add32(Imm32(count), AbsoluteAddress(&counter.m_counter)); - addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord))); -#else -#error "SAMPLING_FLAGS not implemented on this platform." -#endif + killLastResultRegister(); } -#endif -#if ENABLE(OPCODE_SAMPLING) -#if PLATFORM(X86_64) -ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction) -{ - move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86::ecx); - storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86::ecx); -} -#else -ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction) -{ - storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot()); -} -#endif -#endif +#endif // USE(JSVALUE32_64) -#if ENABLE(CODEBLOCK_SAMPLING) -#if PLATFORM(X86_64) -ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) -{ - move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86::ecx); - storePtr(ImmPtr(codeBlock), X86::ecx); -} -#else -ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) -{ - storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot()); -} -#endif -#endif -} +} // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp index da541c5..34debcb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp @@ -32,12 +32,1770 @@ #include "JITStubCall.h" #include "JSArray.h" #include "JSCell.h" +#include "JSFunction.h" +#include "LinkBuffer.h" namespace JSC { +#if USE(JSVALUE32_64) + +void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +{ +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + // (1) This function provides fast property access for string length + Label stringLengthBegin = align(); + + // regT0 holds payload, regT1 holds tag + + Jump string_failureCases1 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)); + + // Checks out okay! - get the length from the Ustring. + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT2); + load32(Address(regT2, OBJECT_OFFSETOF(UString::Rep, len)), regT2); + + Jump string_failureCases3 = branch32(Above, regT2, Imm32(INT_MAX)); + move(regT2, regT0); + move(Imm32(JSValue::Int32Tag), regT1); + + ret(); +#endif + + // (2) Trampolines for the slow cases of op_call / op_call_eval / op_construct. + +#if ENABLE(JIT_OPTIMIZE_CALL) + // VirtualCallLink Trampoline + // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. + Label virtualCallLinkBegin = align(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + + Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + + Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + preserveReturnAddressAfterCall(regT3); + restoreArgumentReference(); + Call callJSFunction2 = call(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + hasCodeBlock2.link(this); + + // Check argCount matches callee arity. + Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callArityCheck2 = call(); + move(regT1, callFrameRegister); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + arityCheckOkay2.link(this); + + isNativeFunc2.link(this); + + compileOpCallInitializeCallFrame(); + + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callLazyLinkCall = call(); + restoreReturnAddressBeforeReturn(regT3); + jump(regT0); +#endif // ENABLE(JIT_OPTIMIZE_CALL) + + // VirtualCall Trampoline + // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. + Label virtualCallBegin = align(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + + Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + + Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + preserveReturnAddressAfterCall(regT3); + restoreArgumentReference(); + Call callJSFunction1 = call(); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + hasCodeBlock3.link(this); + + // Check argCount matches callee arity. + Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callArityCheck1 = call(); + move(regT1, callFrameRegister); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + arityCheckOkay3.link(this); + + isNativeFunc3.link(this); + + compileOpCallInitializeCallFrame(); + loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); + jump(regT0); + +#if PLATFORM(X86) + Label nativeCallThunk = align(); + preserveReturnAddressAfterCall(regT0); + emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address + + // Load caller frame's scope chain into this callframe so that whatever we call can + // get to its global data. + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT1); + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1); + emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + + emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); + + /* We have two structs that we use to describe the stackframe we set up for our + * call to native code. NativeCallFrameStructure describes the how we set up the stack + * in advance of the call. NativeFunctionCalleeSignature describes the callframe + * as the native code expects it. We do this as we are using the fastcall calling + * convention which results in the callee popping its arguments off the stack, but + * not the rest of the callframe so we need a nice way to ensure we increment the + * stack pointer by the right amount after the call. + */ + +#if COMPILER(MSVC) || PLATFORM(LINUX) +#if COMPILER(MSVC) +#pragma pack(push) +#pragma pack(4) +#endif // COMPILER(MSVC) + struct NativeCallFrameStructure { + // CallFrame* callFrame; // passed in EDX + JSObject* callee; + JSValue thisValue; + ArgList* argPointer; + ArgList args; + JSValue result; + }; + struct NativeFunctionCalleeSignature { + JSObject* callee; + JSValue thisValue; + ArgList* argPointer; + }; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif // COMPILER(MSVC) +#else + struct NativeCallFrameStructure { + // CallFrame* callFrame; // passed in ECX + // JSObject* callee; // passed in EDX + JSValue thisValue; + ArgList* argPointer; + ArgList args; + }; + struct NativeFunctionCalleeSignature { + JSValue thisValue; + ArgList* argPointer; + }; +#endif + + const int NativeCallFrameSize = (sizeof(NativeCallFrameStructure) + 15) & ~15; + // Allocate system stack frame + subPtr(Imm32(NativeCallFrameSize), stackPointerRegister); + + // Set up arguments + subPtr(Imm32(1), regT0); // Don't include 'this' in argcount + + // push argcount + storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_argCount))); + + // Calculate the start of the callframe header, and store in regT1 + addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int)sizeof(Register)), callFrameRegister, regT1); + + // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0) + mul32(Imm32(sizeof(Register)), regT0, regT0); + subPtr(regT0, regT1); + storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_args))); + + // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) + addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, args)), stackPointerRegister, regT0); + storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, argPointer))); + + // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this' + loadPtr(Address(regT1, -(int)sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2); + loadPtr(Address(regT1, -(int)sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT3); + storePtr(regT2, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + storePtr(regT3, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + +#if COMPILER(MSVC) || PLATFORM(LINUX) + // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) + addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx); + + // Plant callee + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::eax); + storePtr(X86Registers::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee))); + + // Plant callframe + move(callFrameRegister, X86Registers::edx); + + call(Address(X86Registers::eax, OBJECT_OFFSETOF(JSFunction, m_data))); + + // JSValue is a non-POD type, so eax points to it + emitLoad(0, regT1, regT0, X86Registers::eax); +#else + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::edx); // callee + move(callFrameRegister, X86Registers::ecx); // callFrame + call(Address(X86Registers::edx, OBJECT_OFFSETOF(JSFunction, m_data))); +#endif + + // We've put a few temporaries on the stack in addition to the actual arguments + // so pull them off now + 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)); + + // Grab the return address. + emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3); + + // Restore our caller's "r". + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + + // Return. + restoreReturnAddressBeforeReturn(regT3); + ret(); + + // Handle an exception + sawException1.link(this); + sawException2.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); + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); + restoreReturnAddressBeforeReturn(regT2); + ret(); + +#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) +#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." +#else + breakpoint(); +#endif + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1); + Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2); + Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3); +#endif + + // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. + LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size())); + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail)); + patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail)); + patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail)); +#endif + patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck)); + patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction)); +#if ENABLE(JIT_OPTIMIZE_CALL) + patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck)); + patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction)); + patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall)); +#endif + + CodeRef finalCode = patchBuffer.finalizeCode(); + *executablePool = finalCode.m_executablePool; + + *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); + *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); +#else + UNUSED_PARAM(ctiStringLengthTrampoline); +#endif +#if ENABLE(JIT_OPTIMIZE_CALL) + *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); +#else + UNUSED_PARAM(ctiVirtualCallLink); +#endif +} + +void JIT::emit_op_mov(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + if (m_codeBlock->isConstantRegisterIndex(src)) + emitStore(dst, getConstantOperand(src)); + else { + emitLoad(src, regT1, regT0); + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_mov), dst, regT1, regT0); + } +} + +void JIT::emit_op_end(Instruction* currentInstruction) +{ + if (m_codeBlock->needsFullScopeChain()) + JITStubCall(this, cti_op_end).call(); + ASSERT(returnValueRegister != callFrameRegister); + emitLoad(currentInstruction[1].u.operand, regT1, regT0); + restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); + ret(); +} + +void JIT::emit_op_jmp(Instruction* currentInstruction) +{ + unsigned target = currentInstruction[1].u.operand; + addJump(jump(), target + 1); +} + +void JIT::emit_op_loop(Instruction* currentInstruction) +{ + unsigned target = currentInstruction[1].u.operand; + emitTimeoutCheck(); + addJump(jump(), target + 1); +} + +void JIT::emit_op_loop_if_less(Instruction* currentInstruction) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + emitTimeoutCheck(); + + if (isOperandConstantImmediateInt(op1)) { + emitLoad(op2, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + 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); + 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); +} + +void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_loop_if_less); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); +} + +void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + emitTimeoutCheck(); + + if (isOperandConstantImmediateInt(op1)) { + emitLoad(op2, regT1, regT0); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + 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); + 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); +} + +void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned op1 = currentInstruction[1].u.operand; + unsigned op2 = currentInstruction[2].u.operand; + unsigned target = currentInstruction[3].u.operand; + + if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) + linkSlowCase(iter); // int32 check + linkSlowCase(iter); // int32 check + + JITStubCall stubCall(this, cti_op_loop_if_lesseq); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); +} + +void JIT::emit_op_new_object(Instruction* currentInstruction) +{ + JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand); +} + +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. + emitLoadPayload(proto, regT1); + emitLoadPayload(baseVal, regT0); + emitLoadPayload(value, regT2); + + // Check that baseVal & proto are cells. + emitJumpSlowCaseIfNotJSCell(proto); + emitJumpSlowCaseIfNotJSCell(baseVal); + + // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + 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))); + + // 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. + move(Imm32(JSValue::TrueTag), regT0); + Label loop(this); + + // Load the prototype of the object 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); + + // 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). + isInstance.link(this); + emitStoreBool(dst, regT0); +} + +void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& 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, baseVal); + linkSlowCaseIfNotJSCell(iter, proto); + linkSlowCase(iter); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_instanceof); + stubCall.addArgument(value); + stubCall.addArgument(baseVal); + stubCall.addArgument(proto); + stubCall.call(dst); +} + +void JIT::emit_op_new_func(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_new_func); + stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand))); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_get_global_var(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(currentInstruction[2].u.jsCell); + ASSERT(globalObject->isGlobalObject()); + int index = currentInstruction[3].u.operand; + + loadPtr(&globalObject->d()->registers, regT2); + + emitLoad(index, regT1, regT0, regT2); + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_global_var), dst, regT1, regT0); +} + +void JIT::emit_op_put_global_var(Instruction* currentInstruction) +{ + JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(currentInstruction[1].u.jsCell); + ASSERT(globalObject->isGlobalObject()); + int index = currentInstruction[2].u.operand; + int value = currentInstruction[3].u.operand; + + emitLoad(value, regT1, regT0); + + loadPtr(&globalObject->d()->registers, regT2); + emitStore(index, regT1, regT0, regT2); + map(m_bytecodeIndex + OPCODE_LENGTH(op_put_global_var), value, regT1, regT0); +} + +void JIT::emit_op_get_scoped_var(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int index = currentInstruction[2].u.operand; + int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(); + + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); + while (skip--) + loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2); + + loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2); + + emitLoad(index, regT1, regT0, regT2); + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_scoped_var), dst, regT1, regT0); +} + +void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) +{ + int index = currentInstruction[1].u.operand; + int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain(); + int value = currentInstruction[3].u.operand; + + emitLoad(value, regT1, regT0); + + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); + while (skip--) + loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2); + + loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2); + + emitStore(index, regT1, regT0, regT2); + map(m_bytecodeIndex + OPCODE_LENGTH(op_put_scoped_var), value, regT1, regT0); +} + +void JIT::emit_op_tear_off_activation(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_tear_off_activation); + stubCall.addArgument(currentInstruction[1].u.operand); + stubCall.call(); +} + +void JIT::emit_op_tear_off_arguments(Instruction*) +{ + JITStubCall(this, cti_op_tear_off_arguments).call(); +} + +void JIT::emit_op_new_array(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_new_array); + stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); + stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_resolve(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_resolve); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_to_primitive(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + + Jump isImm = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr))); + isImm.link(this); + + if (dst != src) + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_to_primitive), dst, regT1, regT0); +} + +void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + int dst = currentInstruction[1].u.operand; + + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_to_primitive); + stubCall.addArgument(regT1, regT0); + stubCall.call(dst); +} + +void JIT::emit_op_strcat(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_strcat); + stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); + stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_loop_if_true(Instruction* currentInstruction) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + emitTimeoutCheck(); + + emitLoad(cond, regT1, regT0); + + Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + addJump(branch32(NotEqual, regT0, Imm32(0)), target + 2); + Jump isNotZero = jump(); + + isNotInteger.link(this); + + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag))); + + isNotZero.link(this); +} + +void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_jtrue); + stubCall.addArgument(cond); + stubCall.call(); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); +} + +void JIT::emit_op_resolve_base(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_resolve_base); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_resolve_skip(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_resolve_skip); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); + stubCall.addArgument(Imm32(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain())); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_resolve_global(Instruction* currentInstruction) +{ + // FIXME: Optimize to use patching instead of so many memory accesses. + + unsigned dst = currentInstruction[1].u.operand; + void* globalObject = currentInstruction[2].u.jsCell; + + unsigned currentIndex = m_globalResolveInfoIndex++; + void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure); + void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset); + + // Verify structure. + move(ImmPtr(globalObject), regT0); + loadPtr(structureAddress, regT1); + addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)))); + + // Load property. + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2); + load32(offsetAddr, regT3); + load32(BaseIndex(regT2, regT3, TimesEight), regT0); // payload + load32(BaseIndex(regT2, regT3, TimesEight, 4), regT1); // tag + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_resolve_global), dst, regT1, regT0); +} + +void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + void* globalObject = currentInstruction[2].u.jsCell; + Identifier* ident = &m_codeBlock->identifier(currentInstruction[3].u.operand); + + unsigned currentIndex = m_globalResolveInfoIndex++; + + linkSlowCase(iter); + JITStubCall stubCall(this, cti_op_resolve_global); + stubCall.addArgument(ImmPtr(globalObject)); + stubCall.addArgument(ImmPtr(ident)); + stubCall.addArgument(Imm32(currentIndex)); + stubCall.call(dst); +} + +void JIT::emit_op_not(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + emitLoadTag(src, regT0); + + xor32(Imm32(JSValue::FalseTag), regT0); + addSlowCase(branchTest32(NonZero, regT0, Imm32(~1))); + xor32(Imm32(JSValue::TrueTag), regT0); + + emitStoreBool(dst, regT0, (dst == src)); +} + +void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_not); + stubCall.addArgument(src); + stubCall.call(dst); +} + +void JIT::emit_op_jfalse(Instruction* currentInstruction) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + emitLoad(cond, regT1, regT0); + + Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag)); + addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target + 2); + + Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0)); + addJump(jump(), target + 2); + + isNotInteger.link(this); + + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + zeroDouble(fpRegT0); + emitLoadDouble(cond, fpRegT1); + addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2); + + isTrue.link(this); + isTrue2.link(this); +} + +void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + linkSlowCase(iter); + JITStubCall stubCall(this, cti_op_jtrue); + stubCall.addArgument(cond); + stubCall.call(); + emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // Inverted. +} + +void JIT::emit_op_jtrue(Instruction* currentInstruction) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + emitLoad(cond, regT1, regT0); + + Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag)); + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + + Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); + Jump isFalse2 = branch32(Equal, regT0, Imm32(0)); + addJump(jump(), target + 2); + + isNotInteger.link(this); + + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + zeroDouble(fpRegT0); + emitLoadDouble(cond, fpRegT1); + addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2); + + isFalse.link(this); + isFalse2.link(this); +} + +void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned cond = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + linkSlowCase(iter); + JITStubCall stubCall(this, cti_op_jtrue); + stubCall.addArgument(cond); + stubCall.call(); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); +} + +void JIT::emit_op_jeq_null(Instruction* currentInstruction) +{ + unsigned src = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + + Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + + // 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); + + Jump wasNotImmediate = jump(); + + // Now handle the immediate cases - undefined & null + isImmediate.link(this); + + set32(Equal, regT1, Imm32(JSValue::NullTag), regT2); + set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); + or32(regT2, regT1); + + addJump(branchTest32(NonZero, regT1), target + 2); + + wasNotImmediate.link(this); +} + +void JIT::emit_op_jneq_null(Instruction* currentInstruction) +{ + unsigned src = currentInstruction[1].u.operand; + unsigned target = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + + Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + + // 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); + + Jump wasNotImmediate = jump(); + + // Now handle the immediate cases - undefined & null + isImmediate.link(this); + + set32(Equal, regT1, Imm32(JSValue::NullTag), regT2); + set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); + or32(regT2, regT1); + + addJump(branchTest32(Zero, regT1), target + 2); + + wasNotImmediate.link(this); +} + +void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) +{ + unsigned src = currentInstruction[1].u.operand; + JSCell* ptr = currentInstruction[2].u.jsCell; + 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); +} + +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); + m_jsrSites.append(JSRInfo(storeLocation, label())); +} + +void JIT::emit_op_sret(Instruction* currentInstruction) +{ + jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand)); +} + +void JIT::emit_op_eq(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + emitLoad2(src1, regT1, regT0, src2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, regT3)); + addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag))); + addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag))); + + set8(Equal, regT0, regT2, regT0); + or32(Imm32(JSValue::FalseTag), regT0); + + emitStoreBool(dst, regT0); +} + +void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + + JumpList storeResult; + JumpList genericCase; + + genericCase.append(getSlowCase(iter)); // tags not equal + + linkSlowCase(iter); // tags equal and JSCell + genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr))); + genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr))); + + // String case. + JITStubCall stubCallEqStrings(this, cti_op_eq_strings); + stubCallEqStrings.addArgument(regT0); + stubCallEqStrings.addArgument(regT2); + stubCallEqStrings.call(); + storeResult.append(jump()); + + // Generic case. + genericCase.append(getSlowCase(iter)); // doubles + genericCase.link(this); + JITStubCall stubCallEq(this, cti_op_eq); + stubCallEq.addArgument(op1); + stubCallEq.addArgument(op2); + stubCallEq.call(regT0); + + storeResult.link(this); + or32(Imm32(JSValue::FalseTag), regT0); + emitStoreBool(dst, regT0); +} + +void JIT::emit_op_neq(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + emitLoad2(src1, regT1, regT0, src2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, regT3)); + addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag))); + addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag))); + + set8(NotEqual, regT0, regT2, regT0); + or32(Imm32(JSValue::FalseTag), regT0); + + emitStoreBool(dst, regT0); +} + +void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + + JumpList storeResult; + JumpList genericCase; + + genericCase.append(getSlowCase(iter)); // tags not equal + + linkSlowCase(iter); // tags equal and JSCell + genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr))); + genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr))); + + // String case. + JITStubCall stubCallEqStrings(this, cti_op_eq_strings); + stubCallEqStrings.addArgument(regT0); + stubCallEqStrings.addArgument(regT2); + stubCallEqStrings.call(regT0); + storeResult.append(jump()); + + // Generic case. + genericCase.append(getSlowCase(iter)); // doubles + genericCase.link(this); + JITStubCall stubCallEq(this, cti_op_eq); + stubCallEq.addArgument(regT1, regT0); + stubCallEq.addArgument(regT3, regT2); + stubCallEq.call(regT0); + + storeResult.link(this); + xor32(Imm32(0x1), regT0); + or32(Imm32(JSValue::FalseTag), regT0); + emitStoreBool(dst, regT0); +} + +void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + emitLoadTag(src1, regT0); + emitLoadTag(src2, regT1); + + // Jump to a slow case if either operand is double, or if both operands are + // cells and/or Int32s. + move(regT0, regT2); + and32(regT1, regT2); + addSlowCase(branch32(Below, regT2, Imm32(JSValue::LowestTag))); + addSlowCase(branch32(AboveOrEqual, regT2, Imm32(JSValue::CellTag))); + + if (type == OpStrictEq) + set8(Equal, regT0, regT1, regT0); + else + set8(NotEqual, regT0, regT1, regT0); + + or32(Imm32(JSValue::FalseTag), regT0); + + emitStoreBool(dst, regT0); +} + +void JIT::emit_op_stricteq(Instruction* currentInstruction) +{ + compileOpStrictEq(currentInstruction, OpStrictEq); +} + +void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_stricteq); + stubCall.addArgument(src1); + stubCall.addArgument(src2); + stubCall.call(dst); +} + +void JIT::emit_op_nstricteq(Instruction* currentInstruction) +{ + compileOpStrictEq(currentInstruction, OpNStrictEq); +} + +void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_nstricteq); + stubCall.addArgument(src1); + stubCall.addArgument(src2); + stubCall.call(dst); +} + +void JIT::emit_op_eq_null(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1); + setTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1); + + Jump wasNotImmediate = jump(); + + isImmediate.link(this); + + set8(Equal, regT1, Imm32(JSValue::NullTag), regT2); + set8(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); + or32(regT2, regT1); + + wasNotImmediate.link(this); + + or32(Imm32(JSValue::FalseTag), regT1); + + emitStoreBool(dst, regT1); +} + +void JIT::emit_op_neq_null(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1); + setTest8(Zero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1); + + Jump wasNotImmediate = jump(); + + isImmediate.link(this); + + set8(NotEqual, regT1, Imm32(JSValue::NullTag), regT2); + set8(NotEqual, regT1, Imm32(JSValue::UndefinedTag), regT1); + and32(regT2, regT1); + + wasNotImmediate.link(this); + + or32(Imm32(JSValue::FalseTag), regT1); + + emitStoreBool(dst, regT1); +} + +void JIT::emit_op_resolve_with_base(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_resolve_with_base); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); + stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); + stubCall.call(currentInstruction[2].u.operand); +} + +void JIT::emit_op_new_func_exp(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_new_func_exp); + stubCall.addArgument(ImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand))); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_new_regexp(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_new_regexp); + stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand))); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_throw(Instruction* currentInstruction) +{ + unsigned exception = currentInstruction[1].u.operand; + JITStubCall stubCall(this, cti_op_throw); + stubCall.addArgument(exception); + stubCall.call(); + +#ifndef NDEBUG + // cti_op_throw always changes it's return address, + // this point in the code should never be reached. + breakpoint(); +#endif +} + +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; + + load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0); + + JITStubCall stubCall(this, cti_op_next_pname); + stubCall.addArgument(regT0); + 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); +} + +void JIT::emit_op_push_scope(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_push_scope); + stubCall.addArgument(currentInstruction[1].u.operand); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_pop_scope(Instruction*) +{ + JITStubCall(this, cti_op_pop_scope).call(); +} + +void JIT::emit_op_to_jsnumber(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int src = currentInstruction[2].u.operand; + + emitLoad(src, regT1, regT0); + + Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag)); + addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag))); + isInt32.link(this); + + if (src != dst) + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_to_jsnumber), dst, regT1, regT0); +} + +void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + int dst = currentInstruction[1].u.operand; + + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_to_jsnumber); + stubCall.addArgument(regT1, regT0); + stubCall.call(dst); +} + +void JIT::emit_op_push_new_scope(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_push_new_scope); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); + stubCall.addArgument(currentInstruction[3].u.operand); + stubCall.call(currentInstruction[1].u.operand); +} + +void JIT::emit_op_catch(Instruction* currentInstruction) +{ + unsigned exception = currentInstruction[1].u.operand; + + // This opcode only executes after a return from cti_op_throw. + + // cti_op_throw may have taken us to a call frame further up the stack; reload + // the call frame pointer to adjust. + peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); + + // Now store the exception returned by cti_op_throw. + emitStore(exception, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_catch), exception, regT1, regT0); +#ifdef QT_BUILD_SCRIPT_LIB + JITStubCall stubCall(this, cti_op_debug_catch); + stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); + stubCall.call(); +#endif +} + +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); +} + +void JIT::emit_op_switch_imm(Instruction* currentInstruction) +{ + unsigned tableIndex = currentInstruction[1].u.operand; + unsigned defaultOffset = currentInstruction[2].u.operand; + unsigned scrutinee = currentInstruction[3].u.operand; + + // create jump table for switch destinations, track this switch statement. + SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex); + m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate)); + jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); + + JITStubCall stubCall(this, cti_op_switch_imm); + stubCall.addArgument(scrutinee); + stubCall.addArgument(Imm32(tableIndex)); + stubCall.call(); + jump(regT0); +} + +void JIT::emit_op_switch_char(Instruction* currentInstruction) +{ + unsigned tableIndex = currentInstruction[1].u.operand; + unsigned defaultOffset = currentInstruction[2].u.operand; + unsigned scrutinee = currentInstruction[3].u.operand; + + // create jump table for switch destinations, track this switch statement. + SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex); + m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character)); + jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); + + JITStubCall stubCall(this, cti_op_switch_char); + stubCall.addArgument(scrutinee); + stubCall.addArgument(Imm32(tableIndex)); + stubCall.call(); + jump(regT0); +} + +void JIT::emit_op_switch_string(Instruction* currentInstruction) +{ + unsigned tableIndex = currentInstruction[1].u.operand; + unsigned defaultOffset = currentInstruction[2].u.operand; + unsigned scrutinee = currentInstruction[3].u.operand; + + // create jump table for switch destinations, track this switch statement. + StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex); + m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset)); + + JITStubCall stubCall(this, cti_op_switch_string); + stubCall.addArgument(scrutinee); + stubCall.addArgument(Imm32(tableIndex)); + stubCall.call(); + jump(regT0); +} + +void JIT::emit_op_new_error(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned type = currentInstruction[2].u.operand; + unsigned message = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_new_error); + stubCall.addArgument(Imm32(type)); + stubCall.addArgument(m_codeBlock->getConstant(message)); + stubCall.addArgument(Imm32(m_bytecodeIndex)); + stubCall.call(dst); +} + +void JIT::emit_op_debug(Instruction* currentInstruction) +{ + JITStubCall stubCall(this, cti_op_debug); + stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); + stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); + stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); + stubCall.addArgument(Imm32(currentInstruction[4].u.operand)); + stubCall.call(); +} + + +void JIT::emit_op_enter(Instruction*) +{ + // Even though JIT code doesn't use them, we initialize our constant + // registers to zap stale pointers, to avoid unnecessarily prolonging + // object lifetime and increasing GC pressure. + for (int i = 0; i < m_codeBlock->m_numVars; ++i) + emitStore(i, jsUndefined()); +} + +void JIT::emit_op_enter_with_activation(Instruction* currentInstruction) +{ + emit_op_enter(currentInstruction); + + JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand); +} + +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)); + + // If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation. + if (m_codeBlock->m_numParameters == 1) + JITStubCall(this, cti_op_create_arguments_no_params).call(); + else + JITStubCall(this, cti_op_create_arguments).call(); + + argsNotCell.link(this); + argsNotNull.link(this); +} + +void JIT::emit_op_init_arguments(Instruction*) +{ + emitStore(RegisterFile::ArgumentsRegister, JSValue(), callFrameRegister); +} + +void JIT::emit_op_convert_this(Instruction* currentInstruction) +{ + unsigned thisRegister = currentInstruction[1].u.operand; + + emitLoad(thisRegister, regT1, regT0); + + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); + + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + addSlowCase(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion))); + + map(m_bytecodeIndex + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0); +} + +void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned thisRegister = currentInstruction[1].u.operand; + + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_convert_this); + stubCall.addArgument(regT1, regT0); + stubCall.call(thisRegister); +} + +void JIT::emit_op_profile_will_call(Instruction* currentInstruction) +{ + peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); + Jump noProfiler = branchTestPtr(Zero, Address(regT2)); + + JITStubCall stubCall(this, cti_op_profile_will_call); + stubCall.addArgument(currentInstruction[1].u.operand); + stubCall.call(); + noProfiler.link(this); +} + +void JIT::emit_op_profile_did_call(Instruction* currentInstruction) +{ + peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); + Jump noProfiler = branchTestPtr(Zero, Address(regT2)); + + JITStubCall stubCall(this, cti_op_profile_did_call); + stubCall.addArgument(currentInstruction[1].u.operand); + stubCall.call(); + noProfiler.link(this); +} + +#else // USE(JSVALUE32_64) + #define RECORD_JUMP_TARGET(targetOffset) \ do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false) +void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +{ +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + // (2) The second function provides fast property access for string length + Label stringLengthBegin = align(); + + // Check eax is a string + Jump string_failureCases1 = emitJumpIfNotJSCell(regT0); + Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)); + + // Checks out okay! - get the length from the Ustring. + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT0); + load32(Address(regT0, OBJECT_OFFSETOF(UString::Rep, len)), regT0); + + Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt)); + + // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here. + emitFastArithIntToImmNoCheck(regT0, regT0); + + ret(); +#endif + + // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct. + COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit); + + // VirtualCallLink Trampoline + // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. + Label virtualCallLinkBegin = align(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + + Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + + Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + preserveReturnAddressAfterCall(regT3); + restoreArgumentReference(); + Call callJSFunction2 = call(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + hasCodeBlock2.link(this); + + // Check argCount matches callee arity. + Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callArityCheck2 = call(); + move(regT1, callFrameRegister); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + arityCheckOkay2.link(this); + + isNativeFunc2.link(this); + + compileOpCallInitializeCallFrame(); + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callLazyLinkCall = call(); + restoreReturnAddressBeforeReturn(regT3); + jump(regT0); + + // VirtualCall Trampoline + // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. + Label virtualCallBegin = align(); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + + Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + + Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0)); + preserveReturnAddressAfterCall(regT3); + restoreArgumentReference(); + Call callJSFunction1 = call(); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + hasCodeBlock3.link(this); + + // Check argCount matches callee arity. + Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1); + preserveReturnAddressAfterCall(regT3); + emitPutJITStubArg(regT3, 1); // return address + restoreArgumentReference(); + Call callArityCheck1 = call(); + move(regT1, callFrameRegister); + emitGetJITStubArg(2, regT1); // argCount + restoreReturnAddressBeforeReturn(regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + arityCheckOkay3.link(this); + + isNativeFunc3.link(this); + + compileOpCallInitializeCallFrame(); + loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); + jump(regT0); + + Label nativeCallThunk = align(); + preserveReturnAddressAfterCall(regT0); + emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address + + // Load caller frame's scope chain into this callframe so that whatever we call can + // get to its global data. + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT1); + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1); + emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + + +#if PLATFORM(X86_64) + emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86Registers::ecx); + + // Allocate stack space for our arglist + subPtr(Imm32(sizeof(ArgList)), stackPointerRegister); + COMPILE_ASSERT((sizeof(ArgList) & 0xf) == 0, ArgList_should_by_16byte_aligned); + + // Set up arguments + subPtr(Imm32(1), X86Registers::ecx); // Don't include 'this' in argcount + + // Push argcount + storePtr(X86Registers::ecx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount))); + + // Calculate the start of the callframe header, and store in edx + addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), callFrameRegister, X86Registers::edx); + + // Calculate start of arguments as callframe header - sizeof(Register) * argcount (ecx) + mul32(Imm32(sizeof(Register)), X86Registers::ecx, X86Registers::ecx); + subPtr(X86Registers::ecx, X86Registers::edx); + + // push pointer to arguments + storePtr(X86Registers::edx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args))); + + // ArgList is passed by reference so is stackPointerRegister + move(stackPointerRegister, X86Registers::ecx); + + // edx currently points to the first argument, edx-sizeof(Register) points to 'this' + loadPtr(Address(X86Registers::edx, -(int32_t)sizeof(Register)), X86Registers::edx); + + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::esi); + + move(callFrameRegister, X86Registers::edi); + + call(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_data))); + + addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); +#elif PLATFORM(X86) + emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); + + /* We have two structs that we use to describe the stackframe we set up for our + * call to native code. NativeCallFrameStructure describes the how we set up the stack + * in advance of the call. NativeFunctionCalleeSignature describes the callframe + * as the native code expects it. We do this as we are using the fastcall calling + * convention which results in the callee popping its arguments off the stack, but + * not the rest of the callframe so we need a nice way to ensure we increment the + * stack pointer by the right amount after the call. + */ +#if COMPILER(MSVC) || PLATFORM(LINUX) + struct NativeCallFrameStructure { + // CallFrame* callFrame; // passed in EDX + JSObject* callee; + JSValue thisValue; + ArgList* argPointer; + ArgList args; + JSValue result; + }; + struct NativeFunctionCalleeSignature { + JSObject* callee; + JSValue thisValue; + ArgList* argPointer; + }; +#else + struct NativeCallFrameStructure { + // CallFrame* callFrame; // passed in ECX + // JSObject* callee; // passed in EDX + JSValue thisValue; + ArgList* argPointer; + ArgList args; + }; + struct NativeFunctionCalleeSignature { + JSValue thisValue; + ArgList* argPointer; + }; +#endif + const int NativeCallFrameSize = (sizeof(NativeCallFrameStructure) + 15) & ~15; + // Allocate system stack frame + subPtr(Imm32(NativeCallFrameSize), stackPointerRegister); + + // Set up arguments + subPtr(Imm32(1), regT0); // Don't include 'this' in argcount + + // push argcount + storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_argCount))); + + // Calculate the start of the callframe header, and store in regT1 + addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int)sizeof(Register)), callFrameRegister, regT1); + + // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0) + mul32(Imm32(sizeof(Register)), regT0, regT0); + subPtr(regT0, regT1); + storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_args))); + + // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) + addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, args)), stackPointerRegister, regT0); + storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, argPointer))); + + // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this' + loadPtr(Address(regT1, -(int)sizeof(Register)), regT1); + storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue))); + +#if COMPILER(MSVC) || PLATFORM(LINUX) + // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) + addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx); + + // Plant callee + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::eax); + storePtr(X86Registers::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee))); + + // Plant callframe + move(callFrameRegister, X86Registers::edx); + + call(Address(X86Registers::eax, OBJECT_OFFSETOF(JSFunction, m_data))); + + // JSValue is a non-POD type + loadPtr(Address(X86Registers::eax), X86Registers::eax); +#else + // Plant callee + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::edx); + + // Plant callframe + move(callFrameRegister, X86Registers::ecx); + call(Address(X86Registers::edx, OBJECT_OFFSETOF(JSFunction, m_data))); +#endif + + // We've put a few temporaries on the stack in addition to the actual arguments + // so pull them off now + addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); + +#elif PLATFORM(ARM_TRADITIONAL) + emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); + + // Allocate stack space for our arglist + COMPILE_ASSERT((sizeof(ArgList) & 0x7) == 0, ArgList_should_by_8byte_aligned); + subPtr(Imm32(sizeof(ArgList)), stackPointerRegister); + + // Set up arguments + subPtr(Imm32(1), regT0); // Don't include 'this' in argcount + + // Push argcount + storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount))); + + // Calculate the start of the callframe header, and store in regT1 + move(callFrameRegister, regT1); + sub32(Imm32(RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), regT1); + + // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT1) + mul32(Imm32(sizeof(Register)), regT0, regT0); + subPtr(regT0, regT1); + + // push pointer to arguments + storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args))); + + // Setup arg3: regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this' + loadPtr(Address(regT1, -(int32_t)sizeof(Register)), regT2); + + // Setup arg2: + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT1); + + // Setup arg1: + move(callFrameRegister, regT0); + + // 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); + +#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) +#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." +#else + breakpoint(); +#endif + + // Check for an exception + loadPtr(&(globalData->exception), regT2); + Jump exceptionHandler = branchTestPtr(NonZero, regT2); + + // Grab the return address. + emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); + + // Restore our caller's "r". + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + + // Return. + restoreReturnAddressBeforeReturn(regT1); + ret(); + + // Handle an exception + exceptionHandler.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); + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); + restoreReturnAddressBeforeReturn(regT2); + ret(); + + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1); + Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2); + Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3); +#endif + + // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. + LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size())); + +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail)); + patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail)); + patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail)); +#endif + patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck)); + patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction)); +#if ENABLE(JIT_OPTIMIZE_CALL) + patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck)); + patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction)); + patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall)); +#endif + + CodeRef finalCode = patchBuffer.finalizeCode(); + *executablePool = finalCode.m_executablePool; + + *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); + *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); + *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); +#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); +#else + UNUSED_PARAM(ctiStringLengthTrampoline); +#endif +} + void JIT::emit_op_mov(Instruction* currentInstruction) { int dst = currentInstruction[1].u.operand; @@ -62,7 +1820,7 @@ void JIT::emit_op_mov(Instruction* currentInstruction) void JIT::emit_op_end(Instruction* currentInstruction) { if (m_codeBlock->needsFullScopeChain()) - JITStubCall(this, JITStubs::cti_op_end).call(); + JITStubCall(this, cti_op_end).call(); ASSERT(returnValueRegister != callFrameRegister); emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); @@ -94,7 +1852,7 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op2)) { emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op2imm = getConstantOperandImmediateInt(op2); #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); @@ -103,7 +1861,7 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op1imm = getConstantOperandImmediateInt(op1); #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); @@ -127,7 +1885,7 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op2)) { emitGetVirtualRegister(op1, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) int32_t op2imm = getConstantOperandImmediateInt(op2); #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); @@ -143,7 +1901,7 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) void JIT::emit_op_new_object(Instruction* currentInstruction) { - JITStubCall(this, JITStubs::cti_op_new_object).call(currentInstruction[1].u.operand); + JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand); } void JIT::emit_op_instanceof(Instruction* currentInstruction) @@ -197,8 +1955,8 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) void JIT::emit_op_new_func(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_new_func); - stubCall.addArgument(ImmPtr(m_codeBlock->function(currentInstruction[2].u.operand))); + JITStubCall stubCall(this, cti_op_new_func); + stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand))); stubCall.call(currentInstruction[1].u.operand); } @@ -214,9 +1972,14 @@ void JIT::emit_op_call_eval(Instruction* currentInstruction) void JIT::emit_op_load_varargs(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_load_varargs); - stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); - stubCall.call(currentInstruction[1].u.operand); + int argCountDst = currentInstruction[1].u.operand; + int argsOffset = currentInstruction[2].u.operand; + + JITStubCall stubCall(this, cti_op_load_varargs); + stubCall.addArgument(Imm32(argsOffset)); + stubCall.call(); + // Stores a naked int32 in the register file. + store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register))); } void JIT::emit_op_call_varargs(Instruction* currentInstruction) @@ -273,26 +2036,26 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) void JIT::emit_op_tear_off_activation(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_tear_off_activation); + JITStubCall stubCall(this, cti_op_tear_off_activation); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.call(); } void JIT::emit_op_tear_off_arguments(Instruction*) { - JITStubCall(this, JITStubs::cti_op_tear_off_arguments).call(); + JITStubCall(this, cti_op_tear_off_arguments).call(); } void JIT::emit_op_ret(Instruction* currentInstruction) { #ifdef QT_BUILD_SCRIPT_LIB - JITStubCall stubCall(this, JITStubs::cti_op_debug_return); + JITStubCall stubCall(this, cti_op_debug_return); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); #endif // We could JIT generate the deref, only calling out to C when the refcount hits zero. if (m_codeBlock->needsFullScopeChain()) - JITStubCall(this, JITStubs::cti_op_ret_scopeChain).call(); + JITStubCall(this, cti_op_ret_scopeChain).call(); ASSERT(callFrameRegister != regT1); ASSERT(regT1 != returnValueRegister); @@ -314,7 +2077,7 @@ void JIT::emit_op_ret(Instruction* currentInstruction) void JIT::emit_op_new_array(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_new_array); + JITStubCall stubCall(this, cti_op_new_array); stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); stubCall.call(currentInstruction[1].u.operand); @@ -322,7 +2085,7 @@ void JIT::emit_op_new_array(Instruction* currentInstruction) void JIT::emit_op_resolve(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_resolve); + JITStubCall stubCall(this, cti_op_resolve); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.call(currentInstruction[1].u.operand); } @@ -355,20 +2118,12 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction) void JIT::emit_op_strcat(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_strcat); + JITStubCall stubCall(this, cti_op_strcat); stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); stubCall.call(currentInstruction[1].u.operand); } -void JIT::emit_op_resolve_func(Instruction* currentInstruction) -{ - JITStubCall stubCall(this, JITStubs::cti_op_resolve_func); - stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); - stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); - stubCall.call(currentInstruction[2].u.operand); -} - void JIT::emit_op_loop_if_true(Instruction* currentInstruction) { emitTimeoutCheck(); @@ -386,14 +2141,14 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) }; void JIT::emit_op_resolve_base(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_resolve_base); + JITStubCall stubCall(this, cti_op_resolve_base); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.call(currentInstruction[1].u.operand); } void JIT::emit_op_resolve_skip(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_resolve_skip); + JITStubCall stubCall(this, cti_op_resolve_skip); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(Imm32(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain())); stubCall.call(currentInstruction[1].u.operand); @@ -424,7 +2179,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction) // Slow case noMatch.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_resolve_global); + JITStubCall stubCall(this, cti_op_resolve_global); stubCall.addArgument(ImmPtr(globalObject)); stubCall.addArgument(ImmPtr(ident)); stubCall.addArgument(Imm32(currentIndex)); @@ -540,7 +2295,7 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction) { emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) not32(regT0); emitFastArithIntToImmNoCheck(regT0, regT0); #else @@ -551,7 +2306,7 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction) void JIT::emit_op_resolve_with_base(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_resolve_with_base); + JITStubCall stubCall(this, cti_op_resolve_with_base); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(currentInstruction[2].u.operand); @@ -559,8 +2314,8 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction) void JIT::emit_op_new_func_exp(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_new_func_exp); - stubCall.addArgument(ImmPtr(m_codeBlock->functionExpression(currentInstruction[2].u.operand))); + JITStubCall stubCall(this, cti_op_new_func_exp); + stubCall.addArgument(ImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand))); stubCall.call(currentInstruction[1].u.operand); } @@ -601,7 +2356,7 @@ void JIT::emit_op_bitxor(Instruction* currentInstruction) void JIT::emit_op_new_regexp(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_new_regexp); + JITStubCall stubCall(this, cti_op_new_regexp); stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand))); stubCall.call(currentInstruction[1].u.operand); } @@ -616,7 +2371,7 @@ void JIT::emit_op_bitor(Instruction* currentInstruction) void JIT::emit_op_throw(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_throw); + JITStubCall stubCall(this, cti_op_throw); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.call(); ASSERT(regT0 == returnValueRegister); @@ -629,7 +2384,7 @@ void JIT::emit_op_throw(Instruction* currentInstruction) void JIT::emit_op_next_pname(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_next_pname); + JITStubCall stubCall(this, cti_op_next_pname); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.call(); Jump endOfIter = branchTestPtr(Zero, regT0); @@ -640,14 +2395,37 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction) void JIT::emit_op_push_scope(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_push_scope); + JITStubCall stubCall(this, cti_op_push_scope); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.call(currentInstruction[1].u.operand); } void JIT::emit_op_pop_scope(Instruction*) { - JITStubCall(this, JITStubs::cti_op_pop_scope).call(); + JITStubCall(this, cti_op_pop_scope).call(); +} + +void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned src1 = currentInstruction[2].u.operand; + unsigned src2 = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(src1, regT0, src2, regT1); + + // Jump to a slow case if either operand is a number, or if both are JSCell*s. + move(regT0, regT2); + orPtr(regT1, regT2); + addSlowCase(emitJumpIfJSCell(regT2)); + addSlowCase(emitJumpIfImmediateNumber(regT2)); + + if (type == OpStrictEq) + set32(Equal, regT1, regT0, regT0); + else + set32(NotEqual, regT1, regT0, regT0); + emitTagAsBoolImmediate(regT0); + + emitPutVirtualRegister(dst); } void JIT::emit_op_stricteq(Instruction* currentInstruction) @@ -678,7 +2456,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction) void JIT::emit_op_push_new_scope(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_push_new_scope); + JITStubCall stubCall(this, cti_op_push_new_scope); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(currentInstruction[3].u.operand, regT2); stubCall.call(currentInstruction[1].u.operand); @@ -690,7 +2468,7 @@ void JIT::emit_op_catch(Instruction* currentInstruction) peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); emitPutVirtualRegister(currentInstruction[1].u.operand); #ifdef QT_BUILD_SCRIPT_LIB - JITStubCall stubCall(this, JITStubs::cti_op_debug_catch); + JITStubCall stubCall(this, cti_op_debug_catch); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); #endif @@ -698,7 +2476,7 @@ void JIT::emit_op_catch(Instruction* currentInstruction) void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_jmp_scopes); + JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); addJump(jump(), currentInstruction[2].u.operand + 2); @@ -716,7 +2494,7 @@ void JIT::emit_op_switch_imm(Instruction* currentInstruction) m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate)); jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); - JITStubCall stubCall(this, JITStubs::cti_op_switch_imm); + JITStubCall stubCall(this, cti_op_switch_imm); stubCall.addArgument(scrutinee, regT2); stubCall.addArgument(Imm32(tableIndex)); stubCall.call(); @@ -734,7 +2512,7 @@ void JIT::emit_op_switch_char(Instruction* currentInstruction) m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character)); jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); - JITStubCall stubCall(this, JITStubs::cti_op_switch_char); + JITStubCall stubCall(this, cti_op_switch_char); stubCall.addArgument(scrutinee, regT2); stubCall.addArgument(Imm32(tableIndex)); stubCall.call(); @@ -751,7 +2529,7 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction) StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex); m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset)); - JITStubCall stubCall(this, JITStubs::cti_op_switch_string); + JITStubCall stubCall(this, cti_op_switch_string); stubCall.addArgument(scrutinee, regT2); stubCall.addArgument(Imm32(tableIndex)); stubCall.call(); @@ -760,7 +2538,7 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction) void JIT::emit_op_new_error(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_new_error); + JITStubCall stubCall(this, cti_op_new_error); stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); stubCall.addArgument(ImmPtr(JSValue::encode(m_codeBlock->getConstant(currentInstruction[3].u.operand)))); stubCall.addArgument(Imm32(m_bytecodeIndex)); @@ -769,7 +2547,7 @@ void JIT::emit_op_new_error(Instruction* currentInstruction) void JIT::emit_op_debug(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_debug); + JITStubCall stubCall(this, cti_op_debug); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); @@ -847,16 +2625,16 @@ void JIT::emit_op_enter_with_activation(Instruction* currentInstruction) for (size_t j = 0; j < count; ++j) emitInitRegister(j); - JITStubCall(this, JITStubs::cti_op_push_activation).call(currentInstruction[1].u.operand); + JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand); } void JIT::emit_op_create_arguments(Instruction*) { Jump argsCreated = branchTestPtr(NonZero, Address(callFrameRegister, sizeof(Register) * RegisterFile::ArgumentsRegister)); if (m_codeBlock->m_numParameters == 1) - JITStubCall(this, JITStubs::cti_op_create_arguments_no_params).call(); + JITStubCall(this, cti_op_create_arguments_no_params).call(); else - JITStubCall(this, JITStubs::cti_op_create_arguments).call(); + JITStubCall(this, cti_op_create_arguments).call(); argsCreated.link(this); } @@ -880,7 +2658,7 @@ void JIT::emit_op_profile_will_call(Instruction* currentInstruction) peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); Jump noProfiler = branchTestPtr(Zero, Address(regT1)); - JITStubCall stubCall(this, JITStubs::cti_op_profile_will_call); + JITStubCall stubCall(this, cti_op_profile_will_call); stubCall.addArgument(currentInstruction[1].u.operand, regT1); stubCall.call(); noProfiler.link(this); @@ -892,7 +2670,7 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction) peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); Jump noProfiler = branchTestPtr(Zero, Address(regT1)); - JITStubCall stubCall(this, JITStubs::cti_op_profile_did_call); + JITStubCall stubCall(this, cti_op_profile_did_call); stubCall.addArgument(currentInstruction[1].u.operand, regT1); stubCall.call(); noProfiler.link(this); @@ -905,7 +2683,7 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_convert_this); + JITStubCall stubCall(this, cti_op_convert_this); stubCall.addArgument(regT0); stubCall.call(currentInstruction[1].u.operand); } @@ -922,7 +2700,7 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowC { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_to_primitive); + JITStubCall stubCall(this, cti_op_to_primitive); stubCall.addArgument(regT0); stubCall.call(currentInstruction[1].u.operand); } @@ -938,7 +2716,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas emitFastArithIntToImmNoCheck(regT1, regT1); notImm.link(this); - JITStubCall stubCall(this, JITStubs::cti_op_get_by_val); + JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(currentInstruction[1].u.operand); @@ -964,14 +2742,14 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC unsigned target = currentInstruction[3].u.operand; if (isOperandConstantImmediateInt(op2)) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_loop_if_less); + JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_loop_if_less); + JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(); @@ -979,7 +2757,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC } else { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_loop_if_less); + JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); @@ -993,7 +2771,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo unsigned target = currentInstruction[3].u.operand; if (isOperandConstantImmediateInt(op2)) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_loop_if_lesseq); + JITStubCall stubCall(this, cti_op_loop_if_lesseq); stubCall.addArgument(regT0); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.call(); @@ -1001,7 +2779,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo } else { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_loop_if_lesseq); + JITStubCall stubCall(this, cti_op_loop_if_lesseq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); @@ -1018,7 +2796,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas emitFastArithIntToImmNoCheck(regT1, regT1); notImm.link(this); { - JITStubCall stubCall(this, JITStubs::cti_op_put_by_val); + JITStubCall stubCall(this, cti_op_put_by_val); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.addArgument(currentInstruction[3].u.operand, regT2); @@ -1029,7 +2807,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas // slow cases for immediate int accesses to arrays linkSlowCase(iter); linkSlowCase(iter); { - JITStubCall stubCall(this, JITStubs::cti_op_put_by_val_array); + JITStubCall stubCall(this, cti_op_put_by_val_array); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.addArgument(currentInstruction[3].u.operand, regT2); @@ -1040,7 +2818,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_jtrue); + JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); @@ -1050,7 +2828,7 @@ void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry> { linkSlowCase(iter); xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0); - JITStubCall stubCall(this, JITStubs::cti_op_not); + JITStubCall stubCall(this, cti_op_not); stubCall.addArgument(regT0); stubCall.call(currentInstruction[1].u.operand); } @@ -1058,7 +2836,7 @@ void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry> void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_jtrue); + JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted! @@ -1067,7 +2845,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_bitnot); + JITStubCall stubCall(this, cti_op_bitnot); stubCall.addArgument(regT0); stubCall.call(currentInstruction[1].u.operand); } @@ -1075,7 +2853,7 @@ void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEnt void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_jtrue); + JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); @@ -1084,7 +2862,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_bitxor); + JITStubCall stubCall(this, cti_op_bitxor); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(currentInstruction[1].u.operand); @@ -1093,7 +2871,7 @@ void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEnt void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_bitor); + JITStubCall stubCall(this, cti_op_bitor); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(currentInstruction[1].u.operand); @@ -1102,26 +2880,31 @@ void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntr void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_eq); + JITStubCall stubCall(this, cti_op_eq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); - stubCall.call(currentInstruction[1].u.operand); + stubCall.call(); + emitTagAsBoolImmediate(regT0); + emitPutVirtualRegister(currentInstruction[1].u.operand); } void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_neq); + JITStubCall stubCall(this, cti_op_eq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); - stubCall.call(currentInstruction[1].u.operand); + stubCall.call(); + xor32(Imm32(0x1), regT0); + emitTagAsBoolImmediate(regT0); + emitPutVirtualRegister(currentInstruction[1].u.operand); } void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_stricteq); + JITStubCall stubCall(this, cti_op_stricteq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(currentInstruction[1].u.operand); @@ -1131,7 +2914,7 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase { linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_nstricteq); + JITStubCall stubCall(this, cti_op_nstricteq); stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(currentInstruction[1].u.operand); @@ -1144,7 +2927,7 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); linkSlowCase(iter); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_instanceof); + 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); @@ -1176,11 +2959,12 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_to_jsnumber); + JITStubCall stubCall(this, cti_op_to_jsnumber); stubCall.addArgument(regT0); stubCall.call(currentInstruction[1].u.operand); } +#endif // USE(JSVALUE32_64) } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp index c1e5c29..08b3096 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -47,11 +47,920 @@ using namespace std; namespace JSC { +#if USE(JSVALUE32_64) + +void JIT::emit_op_put_by_index(Instruction* currentInstruction) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_put_by_index); + stubCall.addArgument(base); + stubCall.addArgument(Imm32(property)); + stubCall.addArgument(value); + stubCall.call(); +} + +void JIT::emit_op_put_getter(Instruction* currentInstruction) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned function = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_put_getter); + stubCall.addArgument(base); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property))); + stubCall.addArgument(function); + stubCall.call(); +} + +void JIT::emit_op_put_setter(Instruction* currentInstruction) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned function = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_put_setter); + stubCall.addArgument(base); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property))); + stubCall.addArgument(function); + stubCall.call(); +} + +void JIT::emit_op_del_by_id(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_del_by_id); + stubCall.addArgument(base); + stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property))); + stubCall.call(dst); +} + + +#if !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + +/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */ + +// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair. +void JIT::emit_op_method_check(Instruction*) {} +void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); } +#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS) +#error "JIT_OPTIMIZE_METHOD_CALLS requires JIT_OPTIMIZE_PROPERTY_ACCESS" +#endif + +void JIT::emit_op_get_by_val(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base); + stubCall.addArgument(property); + stubCall.call(dst); +} + +void JIT::emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&) +{ + ASSERT_NOT_REACHED(); +} + +void JIT::emit_op_put_by_val(Instruction* currentInstruction) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_put_by_val); + stubCall.addArgument(base); + stubCall.addArgument(property); + stubCall.addArgument(value); + stubCall.call(); +} + +void JIT::emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&) +{ + ASSERT_NOT_REACHED(); +} + +void JIT::emit_op_get_by_id(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int ident = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_get_by_id_generic); + stubCall.addArgument(base); + stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident)))); + stubCall.call(dst); + + m_propertyAccessInstructionIndex++; +} + +void JIT::emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&) +{ + m_propertyAccessInstructionIndex++; + ASSERT_NOT_REACHED(); +} + +void JIT::emit_op_put_by_id(Instruction* currentInstruction) +{ + int base = currentInstruction[1].u.operand; + int ident = currentInstruction[2].u.operand; + int value = currentInstruction[3].u.operand; + + JITStubCall stubCall(this, cti_op_put_by_id_generic); + stubCall.addArgument(base); + stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident)))); + stubCall.addArgument(value); + stubCall.call(); + + m_propertyAccessInstructionIndex++; +} + +void JIT::emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&) +{ + m_propertyAccessInstructionIndex++; + ASSERT_NOT_REACHED(); +} + +#else // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + +/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */ + +#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS) + +void JIT::emit_op_method_check(Instruction* currentInstruction) +{ + // Assert that the following instruction is a get_by_id. + ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id); + + currentInstruction += OPCODE_LENGTH(op_method_check); + + // Do the method check - check the object & its prototype's structure inline (this is the common case). + m_methodCallCompilationInfo.append(MethodCallCompilationInfo(m_propertyAccessInstructionIndex)); + MethodCallCompilationInfo& info = m_methodCallCompilationInfo.last(); + + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + + emitLoad(base, regT1, regT0); + emitJumpSlowCaseIfNotJSCell(base, regT1); + + Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); + DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT2); + Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); + + // This will be relinked to load the function without doing a load. + DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0); + move(Imm32(JSValue::CellTag), regT1); + Jump match = jump(); + + ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); + ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct); + ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction); + + // Link the failure cases here. + structureCheck.link(this); + protoStructureCheck.link(this); + + // Do a regular(ish) get_by_id (the slow case will be link to + // cti_op_get_by_id_method_check instead of cti_op_get_by_id. + compileGetByIdHotPath(); + + match.link(this); + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_method_check), dst, regT1, regT0); + + // We've already generated the following get_by_id, so make sure it's skipped over. + m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id); +} + +void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + currentInstruction += OPCODE_LENGTH(op_method_check); + + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int ident = currentInstruction[3].u.operand; + + compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter, true); + + // We've already generated the following get_by_id, so make sure it's skipped over. + m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id); +} + +#else //!ENABLE(JIT_OPTIMIZE_METHOD_CALLS) + +// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair. +void JIT::emit_op_method_check(Instruction*) {} +void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); } + +#endif + +void JIT::emit_op_get_by_val(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + emitLoad2(base, regT1, regT0, property, regT3, regT2); + + 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 + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); +} + +void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + 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 + + 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) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + emitLoad2(base, regT1, regT0, property, regT3, regT2); + + 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); + + 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); + + inFastVector.link(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 +} + +void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base not array 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) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + + emitLoad(base, regT1, regT0); + emitJumpSlowCaseIfNotJSCell(base, regT1); + compileGetByIdHotPath(); + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_id), dst, regT1, regT0); +} + +void JIT::compileGetByIdHotPath() +{ + // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched. + // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump + // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label + // to jump back to if one of these trampolies finds a match. + Label hotPathBegin(this); + m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; + m_propertyAccessInstructionIndex++; + + 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); + + Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT2); + Label externalLoadComplete(this); + ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); + ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + + DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload + ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetGetByIdPropertyMapOffset1); + DataLabel32 displacementLabel2 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag + ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetGetByIdPropertyMapOffset2); + + Label putResult(this); + ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); +} + +void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int ident = currentInstruction[3].u.operand; + + compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter); +} + +void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck) +{ + // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset + // so that we only need track one pointer into the slow case code - we track a pointer to the location + // of the call (which we can use to look up the patch information), but should a array-length or + // prototype access trampoline fail we want to bail out back to here. To do so we can subtract back + // the distance from the call to the head of the slow case. + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + + Label coldPathBegin(this); + + JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id); + stubCall.addArgument(regT1, regT0); + stubCall.addArgument(ImmPtr(ident)); + Call call = stubCall.call(dst); + + ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); + + // Track the location of the call; this will be used to recover patch information. + m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; + m_propertyAccessInstructionIndex++; +} + +void JIT::emit_op_put_by_id(Instruction* currentInstruction) +{ + // In order to be able to patch both the Structure, and the object offset, we store one pointer, + // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code + // such that the Structure & offset are always at the same distance from this. + + int base = currentInstruction[1].u.operand; + int value = currentInstruction[3].u.operand; + + emitLoad2(base, regT1, regT0, value, regT3, regT2); + + emitJumpSlowCaseIfNotJSCell(base, regT1); + + Label hotPathBegin(this); + m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; + m_propertyAccessInstructionIndex++; + + // 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); + + // 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); + + DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload + DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag + ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetPutByIdPropertyMapOffset1); + ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetPutByIdPropertyMapOffset2); +} + +void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + int base = currentInstruction[1].u.operand; + int ident = currentInstruction[2].u.operand; + + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_put_by_id); + stubCall.addArgument(regT1, regT0); + stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident)))); + stubCall.addArgument(regT3, regT2); + Call call = stubCall.call(); + + // Track the location of the call; this will be used to recover patch information. + m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; + m_propertyAccessInstructionIndex++; +} + +// Compile a store into an object's property storage. May overwrite base. +void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset) +{ + int offset = cachedOffset; + if (structure->isUsingInlineStorage()) + offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); + else + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + emitStore(offset, valueTag, valuePayload, base); +} + +// Compile a load from an object's property storage. May overwrite base. +void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset) +{ + int offset = cachedOffset; + if (structure->isUsingInlineStorage()) + offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); + else + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + emitLoad(offset, resultTag, resultPayload, base); +} + +void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) +{ + if (base->isUsingInlineStorage()) { + load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]), resultPayload); + load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + 4, resultTag); + return; + } + + size_t offset = cachedOffset * sizeof(JSValue); + + PropertyStorage* protoPropertyStorage = &base->m_externalStorage; + loadPtr(static_cast<void*>(protoPropertyStorage), temp); + load32(Address(temp, offset), resultPayload); + load32(Address(temp, offset + 4), resultTag); +} + +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))); + + // 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()))); + } + + // Reallocate property storage if needed. + Call callTarget; + bool willNeedStorageRealloc = oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity(); + if (willNeedStorageRealloc) { + // This trampoline was called to like a JIT stub; before we can can call again we need to + // remove the return address from the stack, to prevent the stack from becoming misaligned. + preserveReturnAddressAfterCall(regT3); + + JITStubCall stubCall(this, cti_op_put_by_id_transition_realloc); + stubCall.skipArgument(); // base + stubCall.skipArgument(); // ident + stubCall.skipArgument(); // value + stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity())); + stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity())); + stubCall.call(regT0); + + restoreReturnAddressBeforeReturn(regT3); + } + + sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount())); + add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount())); + storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure))); + + load32(Address(stackPointerRegister, offsetof(struct JITStackFrame, args[2]) + sizeof(void*)), regT3); + load32(Address(stackPointerRegister, offsetof(struct JITStackFrame, args[2]) + sizeof(void*) + 4), regT2); + + // Write the value + compilePutDirectOffset(regT0, regT2, regT3, newStructure, cachedOffset); + + ret(); + + ASSERT(!failureCases.empty()); + failureCases.link(this); + restoreArgumentReferenceForTrampoline(); + Call failureCall = tailRecursiveCall(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + patchBuffer.link(failureCall, FunctionPtr(cti_op_put_by_id_fail)); + + if (willNeedStorageRealloc) { + ASSERT(m_calls.size() == 1); + patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc)); + } + + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + stubInfo->stubRoutine = entryLabel; + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relinkCallerToTrampoline(returnAddress, entryLabel); +} + +void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress) +{ + RepatchBuffer repatchBuffer(codeBlock); + + // We don't want to patch more than once - in future go to cti_op_get_by_id_generic. + // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail)); + + int offset = sizeof(JSValue) * cachedOffset; + + // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load + // and makes the subsequent load's offset automatically correct + if (structure->isUsingInlineStorage()) + repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad)); + + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure); + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset1), offset); // payload + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset2), offset + 4); // tag +} + +void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress) +{ + RepatchBuffer repatchBuffer(codeBlock); + + ASSERT(!methodCallLinkInfo.cachedStructure); + methodCallLinkInfo.cachedStructure = structure; + structure->ref(); + + Structure* prototypeStructure = proto->structure(); + ASSERT(!methodCallLinkInfo.cachedPrototypeStructure); + methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure; + prototypeStructure->ref(); + + repatchBuffer.repatch(methodCallLinkInfo.structureLabel, structure); + repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto); + repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure); + repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee); + + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id)); +} + +void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress) +{ + RepatchBuffer repatchBuffer(codeBlock); + + // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. + // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_put_by_id_generic)); + + int offset = sizeof(JSValue) * cachedOffset; + + // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load + // and makes the subsequent load's offset automatically correct + if (structure->isUsingInlineStorage()) + repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad)); + + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure); + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset1), offset); // payload + repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset2), offset + 4); // tag +} + +void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) +{ + StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress); + + // regT0 holds a JSCell* + + // Check for array + Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)); + + // Checks out okay! - get the length from the storage + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); + load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2); + + Jump failureCases2 = branch32(Above, regT2, Imm32(INT_MAX)); + move(regT2, regT0); + move(Imm32(JSValue::Int32Tag), regT1); + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); + patchBuffer.link(failureCases1, slowCaseBegin); + patchBuffer.link(failureCases2, slowCaseBegin); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + // Track the stub we have created so that it will be deleted later. + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + stubInfo->stubRoutine = entryLabel; + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); + + // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail)); +} + +void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) +{ + // regT0 holds a JSCell* + + // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is + // referencing the prototype object - let's speculatively load it's table nice and early!) + JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); + + Jump failureCases1 = checkStructure(regT0, structure); + + // Check the prototype object's Structure had not changed. + Structure** prototypeStructureAddress = &(protoObject->m_structure); +#if PLATFORM(X86_64) + move(ImmPtr(prototypeStructure), regT3); + Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); +#else + Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); +#endif + + // Checks out okay! - getDirectOffset + compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); + patchBuffer.link(failureCases1, slowCaseBegin); + patchBuffer.link(failureCases2, slowCaseBegin); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + // Track the stub we have created so that it will be deleted later. + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + stubInfo->stubRoutine = entryLabel; + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); + + // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); +} + + +void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset) +{ + // regT0 holds a JSCell* + + Jump failureCase = checkStructure(regT0, structure); + compileGetDirectOffset(regT0, regT1, regT0, structure, cachedOffset); + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine; + if (!lastProtoBegin) + lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); + + patchBuffer.link(failureCase, lastProtoBegin); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + + structure->ref(); + polymorphicStructures->list[currentIndex].set(entryLabel, structure); + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); +} + +void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame) +{ + // regT0 holds a JSCell* + + // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is + // referencing the prototype object - let's speculatively load it's table nice and early!) + JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); + + // Check eax is an object of the right Structure. + Jump failureCases1 = checkStructure(regT0, structure); + + // Check the prototype object's Structure had not changed. + Structure** prototypeStructureAddress = &(protoObject->m_structure); +#if PLATFORM(X86_64) + move(ImmPtr(prototypeStructure), regT3); + Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); +#else + Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); +#endif + + compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; + patchBuffer.link(failureCases1, lastProtoBegin); + patchBuffer.link(failureCases2, lastProtoBegin); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + + structure->ref(); + prototypeStructure->ref(); + prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure); + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); +} + +void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame) +{ + // regT0 holds a JSCell* + + ASSERT(count); + + JumpList bucketsOfFail; + + // Check eax is an object of the right Structure. + bucketsOfFail.append(checkStructure(regT0, structure)); + + Structure* currStructure = structure; + RefPtr<Structure>* chainEntries = chain->head(); + JSObject* protoObject = 0; + for (unsigned i = 0; i < count; ++i) { + protoObject = asObject(currStructure->prototypeForLookup(callFrame)); + currStructure = chainEntries[i].get(); + + // Check the prototype object's Structure had not changed. + Structure** prototypeStructureAddress = &(protoObject->m_structure); +#if PLATFORM(X86_64) + move(ImmPtr(currStructure), regT3); + bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); +#else + bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure))); +#endif + } + ASSERT(protoObject); + + compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; + + patchBuffer.link(bucketsOfFail, lastProtoBegin); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + + // Track the stub we have created so that it will be deleted later. + structure->ref(); + chain->ref(); + prototypeStructures->list[currentIndex].set(entryLabel, structure, chain); + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); +} + +void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) +{ + // regT0 holds a JSCell* + + ASSERT(count); + + JumpList bucketsOfFail; + + // Check eax is an object of the right Structure. + bucketsOfFail.append(checkStructure(regT0, structure)); + + Structure* currStructure = structure; + RefPtr<Structure>* chainEntries = chain->head(); + JSObject* protoObject = 0; + for (unsigned i = 0; i < count; ++i) { + protoObject = asObject(currStructure->prototypeForLookup(callFrame)); + currStructure = chainEntries[i].get(); + + // Check the prototype object's Structure had not changed. + Structure** prototypeStructureAddress = &(protoObject->m_structure); +#if PLATFORM(X86_64) + move(ImmPtr(currStructure), regT3); + bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); +#else + bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure))); +#endif + } + ASSERT(protoObject); + + compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + Jump success = jump(); + + LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + // Use the patch information to link the failure cases back to the original slow case routine. + patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall)); + + // On success return back to the hot patch code, at a point it will perform the store to dest for us. + patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + + // Track the stub we have created so that it will be deleted later. + CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); + stubInfo->stubRoutine = entryLabel; + + // Finally patch the jump to slow case back in the hot path to jump here instead. + CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(jumpLocation, entryLabel); + + // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); +} + +/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */ + +#endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) + +#else // USE(JSVALUE32_64) + void JIT::emit_op_get_by_val(Instruction* currentInstruction) { emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); -#if USE(ALTERNATE_JSIMMEDIATE) +#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 @@ -78,7 +987,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) { emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) // See comment in op_get_by_val. zeroExtend32ToPtr(regT1, regT1); #else @@ -105,7 +1014,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) void JIT::emit_op_put_by_index(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_put_by_index); + JITStubCall stubCall(this, cti_op_put_by_index); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.addArgument(Imm32(currentInstruction[2].u.operand)); stubCall.addArgument(currentInstruction[3].u.operand, regT2); @@ -114,7 +1023,7 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction) void JIT::emit_op_put_getter(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_put_getter); + JITStubCall stubCall(this, cti_op_put_getter); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(currentInstruction[3].u.operand, regT2); @@ -123,7 +1032,7 @@ void JIT::emit_op_put_getter(Instruction* currentInstruction) void JIT::emit_op_put_setter(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_put_setter); + JITStubCall stubCall(this, cti_op_put_setter); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(currentInstruction[3].u.operand, regT2); @@ -132,7 +1041,7 @@ void JIT::emit_op_put_setter(Instruction* currentInstruction) void JIT::emit_op_del_by_id(Instruction* currentInstruction) { - JITStubCall stubCall(this, JITStubs::cti_op_del_by_id); + JITStubCall stubCall(this, cti_op_del_by_id); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.call(currentInstruction[1].u.operand); @@ -157,7 +1066,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction) Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); emitGetVirtualRegister(baseVReg, regT0); - JITStubCall stubCall(this, JITStubs::cti_op_get_by_id_generic); + JITStubCall stubCall(this, cti_op_get_by_id_generic); stubCall.addArgument(regT0); stubCall.addArgument(ImmPtr(ident)); stubCall.call(resultVReg); @@ -178,7 +1087,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1); - JITStubCall stubCall(this, JITStubs::cti_op_put_by_id_generic); + JITStubCall stubCall(this, cti_op_put_by_id_generic); stubCall.addArgument(regT0); stubCall.addArgument(ImmPtr(ident)); stubCall.addArgument(regT1); @@ -213,13 +1122,20 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) // Do the method check - check the object & its prototype's structure inline (this is the common case). m_methodCallCompilationInfo.append(MethodCallCompilationInfo(m_propertyAccessInstructionIndex)); MethodCallCompilationInfo& info = m_methodCallCompilationInfo.last(); + Jump notCell = emitJumpIfNotJSCell(regT0); + + BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck); + Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT1); Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); // This will be relinked to load the function without doing a load. DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0); + + END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck); + Jump match = jump(); ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); @@ -249,7 +1165,7 @@ void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowC unsigned baseVReg = currentInstruction[2].u.operand; Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); - compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, m_propertyAccessInstructionIndex++, true); + compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, true); // We've already generated the following get_by_id, so make sure it's skipped over. m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id); @@ -283,6 +1199,8 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert emitJumpSlowCaseIfNotJSCell(regT0, baseVReg); + BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); + Label hotPathBegin(this); m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; @@ -301,6 +1219,9 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset); Label putResult(this); + + END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); + ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); } @@ -310,10 +1231,10 @@ void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCase unsigned baseVReg = currentInstruction[2].u.operand; Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); - compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, m_propertyAccessInstructionIndex++, false); + compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, false); } -void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex, bool isMethodCheck) +void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck) { // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset // so that we only need track one pointer into the slow case code - we track a pointer to the location @@ -324,18 +1245,23 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident linkSlowCaseIfNotJSCell(iter, baseVReg); linkSlowCase(iter); + BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); + #ifndef NDEBUG Label coldPathBegin(this); #endif - JITStubCall stubCall(this, isMethodCheck ? JITStubs::cti_op_get_by_id_method_check : JITStubs::cti_op_get_by_id); + JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id); stubCall.addArgument(regT0); stubCall.addArgument(ImmPtr(ident)); Call call = stubCall.call(resultVReg); + END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); + ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); // Track the location of the call; this will be used to recover patch information. - m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call; + m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; + m_propertyAccessInstructionIndex++; } void JIT::emit_op_put_by_id(Instruction* currentInstruction) @@ -354,6 +1280,8 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) // Jump to a slow case if either the base object is an immediate, or if the Structure does not match. emitJumpSlowCaseIfNotJSCell(regT0, baseVReg); + BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById); + Label hotPathBegin(this); m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin; @@ -369,6 +1297,9 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset)); + + END_UNINTERRUPTED_SEQUENCE(sequencePutById); + ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset); } @@ -382,7 +1313,7 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase linkSlowCaseIfNotJSCell(iter, baseVReg); linkSlowCase(iter); - JITStubCall stubCall(this, JITStubs::cti_op_put_by_id); + JITStubCall stubCall(this, cti_op_put_by_id); stubCall.addArgument(regT0); stubCall.addArgument(ImmPtr(ident)); stubCall.addArgument(regT1); @@ -465,13 +1396,14 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure // remove the return address from the stack, to prevent the stack from becoming misaligned. preserveReturnAddressAfterCall(regT3); - JITStubCall stubCall(this, JITStubs::cti_op_put_by_id_transition_realloc); - stubCall.addArgument(regT0); + JITStubCall stubCall(this, cti_op_put_by_id_transition_realloc); + stubCall.skipArgument(); // base + stubCall.skipArgument(); // ident + stubCall.skipArgument(); // value stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity())); stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity())); - stubCall.addArgument(regT1); // This argument is not used in the stub; we set it up on the stack so that it can be restored, below. stubCall.call(regT0); - emitGetJITStubArg(4, regT1); + emitGetJITStubArg(2, regT1); restoreReturnAddressBeforeReturn(regT3); } @@ -494,11 +1426,11 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); - patchBuffer.link(failureCall, FunctionPtr(JITStubs::cti_op_put_by_id_fail)); + patchBuffer.link(failureCall, FunctionPtr(cti_op_put_by_id_fail)); if (willNeedStorageRealloc) { ASSERT(m_calls.size() == 1); - patchBuffer.link(m_calls[0].from, FunctionPtr(JITStubs::cti_op_put_by_id_transition_realloc)); + patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc)); } CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); @@ -512,8 +1444,8 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St RepatchBuffer repatchBuffer(codeBlock); // We don't want to patch more than once - in future go to cti_op_get_by_id_generic. - // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now. - repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_self_fail)); + // Should probably go to cti_op_get_by_id_fail, but that doesn't do anything interesting right now. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail)); int offset = sizeof(JSValue) * cachedOffset; @@ -527,7 +1459,7 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset), offset); } -void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto) +void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress) { RepatchBuffer repatchBuffer(codeBlock); @@ -544,6 +1476,8 @@ void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodC repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto); repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure); repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee); + + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id)); } void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress) @@ -551,8 +1485,8 @@ void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, RepatchBuffer repatchBuffer(codeBlock); // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. - // Should probably go to JITStubs::cti_op_put_by_id_fail, but that doesn't do anything interesting right now. - repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(JITStubs::cti_op_put_by_id_generic)); + // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now. + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_put_by_id_generic)); int offset = sizeof(JSValue) * cachedOffset; @@ -602,7 +1536,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) repatchBuffer.relink(jumpLocation, entryLabel); // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. - repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_array_fail)); + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail)); } void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) @@ -648,7 +1582,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str repatchBuffer.relink(jumpLocation, entryLabel); // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. - repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_proto_list)); + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); } void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset) @@ -827,13 +1761,15 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str repatchBuffer.relink(jumpLocation, entryLabel); // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. - repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_proto_list)); + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); } /* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */ #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) +#endif // USE(JSVALUE32_64) + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h index bc07178..cb5354b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h @@ -37,32 +37,40 @@ namespace JSC { JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) , m_stub(reinterpret_cast<void*>(stub)) - , m_returnType(Value) - , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference(); + , m_returnType(Cell) + , m_stackIndex(stackIndexStart) { } JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) , m_stub(reinterpret_cast<void*>(stub)) - , m_returnType(Value) - , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference(); + , m_returnType(Cell) + , m_stackIndex(stackIndexStart) { } JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) , m_stub(reinterpret_cast<void*>(stub)) - , m_returnType(Value) - , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference(); + , m_returnType(VoidPtr) + , m_stackIndex(stackIndexStart) { } JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) , m_stub(reinterpret_cast<void*>(stub)) - , m_returnType(Value) - , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference(); + , m_returnType(Int) + , m_stackIndex(stackIndexStart) + { + } + + JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) + : m_jit(jit) + , m_stub(reinterpret_cast<void*>(stub)) + , m_returnType(Int) + , m_stackIndex(stackIndexStart) { } @@ -70,30 +78,78 @@ namespace JSC { : m_jit(jit) , m_stub(reinterpret_cast<void*>(stub)) , m_returnType(Void) - , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference(); + , m_stackIndex(stackIndexStart) + { + } + +#if USE(JSVALUE32_64) + JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) + : m_jit(jit) + , m_stub(reinterpret_cast<void*>(stub)) + , m_returnType(Value) + , m_stackIndex(stackIndexStart) { } +#endif // Arguments are added first to last. + void skipArgument() + { + m_stackIndex += stackIndexStep; + } + void addArgument(JIT::Imm32 argument) { - m_jit->poke(argument, m_argumentIndex); - ++m_argumentIndex; + m_jit->poke(argument, m_stackIndex); + m_stackIndex += stackIndexStep; } void addArgument(JIT::ImmPtr argument) { - m_jit->poke(argument, m_argumentIndex); - ++m_argumentIndex; + m_jit->poke(argument, m_stackIndex); + m_stackIndex += stackIndexStep; } void addArgument(JIT::RegisterID argument) { - m_jit->poke(argument, m_argumentIndex); - ++m_argumentIndex; + m_jit->poke(argument, m_stackIndex); + m_stackIndex += stackIndexStep; + } + + void addArgument(const JSValue& value) + { + m_jit->poke(JIT::Imm32(value.payload()), m_stackIndex); + m_jit->poke(JIT::Imm32(value.tag()), m_stackIndex + 1); + m_stackIndex += stackIndexStep; + } + + void addArgument(JIT::RegisterID tag, JIT::RegisterID payload) + { + m_jit->poke(payload, m_stackIndex); + m_jit->poke(tag, m_stackIndex + 1); + m_stackIndex += stackIndexStep; + } + +#if USE(JSVALUE32_64) + void addArgument(unsigned srcVirtualRegister) + { + if (m_jit->m_codeBlock->isConstantRegisterIndex(srcVirtualRegister)) { + addArgument(m_jit->getConstantOperand(srcVirtualRegister)); + return; + } + + m_jit->emitLoad(srcVirtualRegister, JIT::regT1, JIT::regT0); + addArgument(JIT::regT1, JIT::regT0); } + void getArgument(size_t argumentNumber, JIT::RegisterID tag, JIT::RegisterID payload) + { + size_t stackIndex = stackIndexStart + (argumentNumber * stackIndexStep); + m_jit->peek(payload, stackIndex); + m_jit->peek(tag, stackIndex + 1); + } +#else void addArgument(unsigned src, JIT::RegisterID scratchRegister) // src is a virtual register. { if (m_jit->m_codeBlock->isConstantRegisterIndex(src)) @@ -104,6 +160,7 @@ namespace JSC { } m_jit->killLastResultRegister(); } +#endif JIT::Call call() { @@ -121,21 +178,42 @@ namespace JSC { m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, false); #endif +#if USE(JSVALUE32_64) + m_jit->unmap(); +#else m_jit->killLastResultRegister(); +#endif return call; } +#if USE(JSVALUE32_64) + JIT::Call call(unsigned dst) // dst is a virtual register. + { + ASSERT(m_returnType == Value || m_returnType == Cell); + JIT::Call call = this->call(); + if (m_returnType == Value) + m_jit->emitStore(dst, JIT::regT1, JIT::regT0); + else + m_jit->emitStoreCell(dst, JIT::returnValueRegister); + return call; + } +#else JIT::Call call(unsigned dst) // dst is a virtual register. { - ASSERT(m_returnType == Value); + ASSERT(m_returnType == VoidPtr || m_returnType == Cell); JIT::Call call = this->call(); m_jit->emitPutVirtualRegister(dst); return call; } +#endif - JIT::Call call(JIT::RegisterID dst) + JIT::Call call(JIT::RegisterID dst) // dst is a machine register. { - ASSERT(m_returnType == Value); +#if USE(JSVALUE32_64) + ASSERT(m_returnType == Value || m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell); +#else + ASSERT(m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell); +#endif JIT::Call call = this->call(); if (dst != JIT::returnValueRegister) m_jit->move(JIT::returnValueRegister, dst); @@ -143,25 +221,13 @@ namespace JSC { } private: + static const size_t stackIndexStep = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 2 : 1; + static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference(). + JIT* m_jit; void* m_stub; - enum { Value, Void } m_returnType; - size_t m_argumentIndex; - }; - - class CallEvalJITStub : public JITStubCall { - public: - CallEvalJITStub(JIT* jit, Instruction* instruction) - : JITStubCall(jit, JITStubs::cti_op_call_eval) - { - int callee = instruction[2].u.operand; - int argCount = instruction[3].u.operand; - int registerOffset = instruction[4].u.operand; - - addArgument(callee, JIT::regT2); - addArgument(JIT::Imm32(registerOffset)); - addArgument(JIT::Imm32(argCount)); - } + enum { Void, VoidPtr, Int, Value, Cell } m_returnType; + size_t m_stackIndex; }; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp index 7928593..a110dcd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp @@ -56,6 +56,7 @@ #include "RegExpPrototype.h" #include "Register.h" #include "SamplingTool.h" +#include <stdarg.h> #include <stdio.h> #ifdef QT_BUILD_SCRIPT_LIB @@ -66,13 +67,18 @@ using namespace std; namespace JSC { - #if PLATFORM(DARWIN) || PLATFORM(WIN_OS) #define SYMBOL_STRING(name) "_" #name #else #define SYMBOL_STRING(name) #name #endif +#if PLATFORM(IPHONE) +#define THUMB_FUNC_PARAM(name) SYMBOL_STRING(name) +#else +#define THUMB_FUNC_PARAM(name) +#endif + #if PLATFORM(DARWIN) // Mach-O platform #define HIDE_SYMBOL(name) ".private_extern _" #name @@ -86,6 +92,271 @@ namespace JSC { #define HIDE_SYMBOL(name) #endif +#if USE(JSVALUE32_64) + +#if COMPILER(GCC) && PLATFORM(X86) + +// These ASSERTs remind you that, if you change the layout of JITStackFrame, you +// need to change the assembly trampolines below to match. +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment); +COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline); + +asm volatile ( +".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" +SYMBOL_STRING(ctiTrampoline) ":" "\n" + "pushl %ebp" "\n" + "movl %esp, %ebp" "\n" + "pushl %esi" "\n" + "pushl %edi" "\n" + "pushl %ebx" "\n" + "subl $0x3c, %esp" "\n" + "movl $512, %esi" "\n" + "movl 0x58(%esp), %edi" "\n" + "call *0x50(%esp)" "\n" + "addl $0x3c, %esp" "\n" + "popl %ebx" "\n" + "popl %edi" "\n" + "popl %esi" "\n" + "popl %ebp" "\n" + "ret" "\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" + "addl $0x3c, %esp" "\n" + "popl %ebx" "\n" + "popl %edi" "\n" + "popl %esi" "\n" + "popl %ebp" "\n" + "ret" "\n" +); + +asm volatile ( +".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" +SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" + "addl $0x3c, %esp" "\n" + "popl %ebx" "\n" + "popl %edi" "\n" + "popl %esi" "\n" + "popl %ebp" "\n" + "ret" "\n" +); + +#elif COMPILER(GCC) && PLATFORM(X86_64) + +#if USE(JIT_STUB_ARGUMENT_VA_LIST) +#error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64." +#endif + +// These ASSERTs remind you that, if you change the layout of JITStackFrame, you +// need to change the assembly trampolines below to match. +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 32 == 0x0, JITStackFrame_maintains_32byte_stack_alignment); +COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_stub_argument_space_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x90, JITStackFrame_callFrame_offset_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_offset_matches_ctiTrampoline); + +asm volatile ( +".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" +SYMBOL_STRING(ctiTrampoline) ":" "\n" + "pushq %rbp" "\n" + "movq %rsp, %rbp" "\n" + "pushq %r12" "\n" + "pushq %r13" "\n" + "pushq %r14" "\n" + "pushq %r15" "\n" + "pushq %rbx" "\n" + "subq $0x48, %rsp" "\n" + "movq $512, %r12" "\n" + "movq $0xFFFF000000000000, %r14" "\n" + "movq $0xFFFF000000000002, %r15" "\n" + "movq 0x90(%rsp), %r13" "\n" + "call *0x80(%rsp)" "\n" + "addq $0x48, %rsp" "\n" + "popq %rbx" "\n" + "popq %r15" "\n" + "popq %r14" "\n" + "popq %r13" "\n" + "popq %r12" "\n" + "popq %rbp" "\n" + "ret" "\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" + "addq $0x48, %rsp" "\n" + "popq %rbx" "\n" + "popq %r15" "\n" + "popq %r14" "\n" + "popq %r13" "\n" + "popq %r12" "\n" + "popq %rbp" "\n" + "ret" "\n" +); + +asm volatile ( +".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" +SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" + "addq $0x48, %rsp" "\n" + "popq %rbx" "\n" + "popq %r15" "\n" + "popq %r14" "\n" + "popq %r13" "\n" + "popq %r12" "\n" + "popq %rbp" "\n" + "ret" "\n" +); + +#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) + +#if USE(JIT_STUB_ARGUMENT_VA_LIST) +#error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." +#endif + +asm volatile ( +".text" "\n" +".align 2" "\n" +".globl " SYMBOL_STRING(ctiTrampoline) "\n" +".thumb" "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" +SYMBOL_STRING(ctiTrampoline) ":" "\n" + "sub sp, sp, #0x3c" "\n" + "str lr, [sp, #0x20]" "\n" + "str r4, [sp, #0x24]" "\n" + "str r5, [sp, #0x28]" "\n" + "str r6, [sp, #0x2c]" "\n" + "str r1, [sp, #0x30]" "\n" + "str r2, [sp, #0x34]" "\n" + "str r3, [sp, #0x38]" "\n" + "cpy r5, r2" "\n" + "mov r6, #512" "\n" + "blx r0" "\n" + "ldr r6, [sp, #0x2c]" "\n" + "ldr r5, [sp, #0x28]" "\n" + "ldr r4, [sp, #0x24]" "\n" + "ldr lr, [sp, #0x20]" "\n" + "add sp, sp, #0x3c" "\n" + "bx lr" "\n" +); + +asm volatile ( +".text" "\n" +".align 2" "\n" +".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +".thumb" "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" +SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" + "cpy r0, sp" "\n" + "bl " SYMBOL_STRING(cti_vm_throw) "\n" + "ldr r6, [sp, #0x2c]" "\n" + "ldr r5, [sp, #0x28]" "\n" + "ldr r4, [sp, #0x24]" "\n" + "ldr lr, [sp, #0x20]" "\n" + "add sp, sp, #0x3c" "\n" + "bx lr" "\n" +); + +asm volatile ( +".text" "\n" +".align 2" "\n" +".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +".thumb" "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" +SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" + "ldr r6, [sp, #0x2c]" "\n" + "ldr r5, [sp, #0x28]" "\n" + "ldr r4, [sp, #0x24]" "\n" + "ldr lr, [sp, #0x20]" "\n" + "add sp, sp, #0x3c" "\n" + "bx lr" "\n" +); + +#elif COMPILER(MSVC) + +#if USE(JIT_STUB_ARGUMENT_VA_LIST) +#error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC." +#endif + +// These ASSERTs remind you that, if you change the layout of JITStackFrame, you +// need to change the assembly trampolines below to match. +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment); +COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline); + +extern "C" { + + __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*) + { + __asm { + push ebp; + mov ebp, esp; + push esi; + push edi; + push ebx; + sub esp, 0x3c; + mov esi, 512; + mov ecx, esp; + mov edi, [esp + 0x58]; + call [esp + 0x50]; + add esp, 0x3c; + pop ebx; + pop edi; + pop esi; + pop ebp; + ret; + } + } + + __declspec(naked) void ctiVMThrowTrampoline() + { + __asm { + mov ecx, esp; + call cti_vm_throw; + add esp, 0x3c; + pop ebx; + pop edi; + pop esi; + pop ebp; + ret; + } + } + + __declspec(naked) void ctiOpThrowNotCaught() + { + __asm { + add esp, 0x3c; + pop ebx; + pop edi; + pop esi; + pop ebp; + ret; + } + } +} + +#endif // COMPILER(GCC) && PLATFORM(X86) + +#else // USE(JSVALUE32_64) + #if COMPILER(GCC) && PLATFORM(X86) // These ASSERTs remind you that, if you change the layout of JITStackFrame, you @@ -151,9 +422,9 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" // These ASSERTs remind you that, if you change the layout of JITStackFrame, you // need to change the assembly trampolines below to match. -COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x90, JITStackFrame_callFrame_offset_matches_ctiTrampoline); -COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_offset_matches_ctiTrampoline); -COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_stub_argument_space_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x48, JITStackFrame_code_offset_matches_ctiTrampoline); +COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x78, JITStackFrame_stub_argument_space_matches_ctiTrampoline); asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" @@ -166,13 +437,20 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "pushq %r14" "\n" "pushq %r15" "\n" "pushq %rbx" "\n" + // Form the JIT stubs area + "pushq %r9" "\n" + "pushq %r8" "\n" + "pushq %rcx" "\n" + "pushq %rdx" "\n" + "pushq %rsi" "\n" + "pushq %rdi" "\n" "subq $0x48, %rsp" "\n" "movq $512, %r12" "\n" "movq $0xFFFF000000000000, %r14" "\n" "movq $0xFFFF000000000002, %r15" "\n" - "movq 0x90(%rsp), %r13" "\n" - "call *0x80(%rsp)" "\n" - "addq $0x48, %rsp" "\n" + "movq %rdx, %r13" "\n" + "call *%rdi" "\n" + "addq $0x78, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" "popq %r14" "\n" @@ -188,7 +466,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" "call " SYMBOL_STRING(cti_vm_throw) "\n" - "addq $0x48, %rsp" "\n" + "addq $0x78, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" "popq %r14" "\n" @@ -202,7 +480,7 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" - "addq $0x48, %rsp" "\n" + "addq $0x78, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" "popq %r14" "\n" @@ -212,7 +490,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM_ARM_ARCH(7) +#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." @@ -224,9 +502,9 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" HIDE_SYMBOL(ctiTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" - "sub sp, sp, #0x3c" "\n" + "sub sp, sp, #0x40" "\n" "str lr, [sp, #0x20]" "\n" "str r4, [sp, #0x24]" "\n" "str r5, [sp, #0x28]" "\n" @@ -241,7 +519,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" "ldr lr, [sp, #0x20]" "\n" - "add sp, sp, #0x3c" "\n" + "add sp, sp, #0x40" "\n" "bx lr" "\n" ); @@ -251,7 +529,7 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" "bl " SYMBOL_STRING(cti_vm_throw) "\n" @@ -259,7 +537,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" "ldr lr, [sp, #0x20]" "\n" - "add sp, sp, #0x3c" "\n" + "add sp, sp, #0x40" "\n" "bx lr" "\n" ); @@ -269,7 +547,7 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" @@ -279,6 +557,49 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "bx lr" "\n" ); +#elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL) + +asm volatile ( +".globl " SYMBOL_STRING(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" + "mov r5, #512" "\n" + // r0 contains the code + "add r8, pc, #4" "\n" + "str r8, [sp, #-4]!" "\n" + "mov pc, r0" "\n" + "add sp, sp, #32" "\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" +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" + +// Both has the same return sequence +".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" + "add sp, sp, #32" "\n" + "ldmia sp!, {r4-r8, lr}" "\n" + "add sp, sp, #12" "\n" + "mov pc, lr" "\n" +); + #elif COMPILER(MSVC) #if USE(JIT_STUB_ARGUMENT_VA_LIST) @@ -319,7 +640,7 @@ extern "C" { { __asm { mov ecx, esp; - call JITStubs::cti_vm_throw; + call cti_vm_throw; add esp, 0x1c; pop ebx; pop edi; @@ -342,7 +663,9 @@ extern "C" { } } -#endif +#endif // COMPILER(GCC) && PLATFORM(X86) + +#endif // USE(JSVALUE32_64) #if ENABLE(OPCODE_SAMPLING) #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler() @@ -352,9 +675,9 @@ extern "C" { JITThunks::JITThunks(JSGlobalData* globalData) { - JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiArrayLengthTrampoline, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); + JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types), // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT // macros. @@ -367,7 +690,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == 0x34); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == 0x38); // The fifth argument is the first item already on the stack. - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x3c); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x40); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 0x1C); #endif @@ -375,7 +698,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) -NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot) +NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo) { // The interpreter checks for recursion here; I do not believe this can occur in CTI. @@ -384,33 +707,31 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co // Uncacheable: give up. if (!slot.isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_put_by_id_generic)); + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_put_by_id_generic)); + if (structure->isUncacheableDictionary()) { + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } // If baseCell != base, then baseCell must be a proxy for another object. if (baseCell != slot.base()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_put_by_id_generic)); + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } - StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress); - // Cache hit: Specialize instruction and ref Structures. // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { StructureChain* prototypeChain = structure->prototypeChain(callFrame); if (!prototypeChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_put_by_id_generic)); + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain); @@ -423,14 +744,14 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress); } -NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot) +NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo) { // FIXME: Write a test that proves we need to check for recursion here just // like the interpreter does, then add a check for recursion. // FIXME: Cache property access for immediates. if (!baseValue.isCell()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_generic)); + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -450,23 +771,18 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co // Uncacheable: give up. if (!slot.isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_generic)); + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_generic)); + if (structure->isUncacheableDictionary()) { + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } - // In the interpreter the last structure is trapped here; in CTI we use the - // *_second method to achieve a similar (but not quite the same) effect. - - StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress); - // Cache hit: Specialize instruction and ref Structures. if (slot.slotBase() == baseValue) { @@ -495,20 +811,20 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); if (!count) { - stubInfo->opcodeID = op_get_by_id_generic; + stubInfo->accessType = access_get_by_id_generic; return; } StructureChain* prototypeChain = structure->prototypeChain(callFrame); if (!prototypeChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(JITStubs::cti_op_get_by_id_generic)); + 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); } -#endif +#endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #define SETUP_VA_LISTL_ARGS va_list vl_args; va_start(vl_args, args) @@ -585,25 +901,23 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD #define CHECK_FOR_EXCEPTION() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception != JSValue())) \ + if (UNLIKELY(stackFrame.globalData->exception)) \ VM_THROW_EXCEPTION(); \ } while (0) #define CHECK_FOR_EXCEPTION_AT_END() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception != JSValue())) \ + if (UNLIKELY(stackFrame.globalData->exception)) \ VM_THROW_EXCEPTION_AT_END(); \ } while (0) #define CHECK_FOR_EXCEPTION_VOID() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception != JSValue())) { \ + if (UNLIKELY(stackFrame.globalData->exception)) { \ VM_THROW_EXCEPTION_AT_END(); \ return; \ } \ } while (0) -namespace JITStubs { - -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) #define DEFINE_STUB_FUNCTION(rtype, op) \ extern "C" { \ @@ -615,7 +929,7 @@ namespace JITStubs { ".globl " SYMBOL_STRING(cti_##op) "\n" \ HIDE_SYMBOL(cti_##op) "\n" \ ".thumb" "\n" \ - ".thumb_func " SYMBOL_STRING(cti_##op) "\n" \ + ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \ SYMBOL_STRING(cti_##op) ":" "\n" \ "str lr, [sp, #0x1c]" "\n" \ "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ @@ -628,7 +942,7 @@ namespace JITStubs { #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif -DEFINE_STUB_FUNCTION(JSObject*, op_convert_this) +DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this) { STUB_INIT_STACK_FRAME(stackFrame); @@ -637,7 +951,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_convert_this) JSObject* result = v1.toThisObject(callFrame); CHECK_FOR_EXCEPTION_AT_END(); - return result; + return JSValue::encode(result); } DEFINE_STUB_FUNCTION(void, op_end) @@ -677,8 +991,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) } if (rightIsNumber & leftIsString) { - RefPtr<UString::Rep> value = v2.isInt32Fast() ? - concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) : + RefPtr<UString::Rep> value = v2.isInt32() ? + concatenate(asString(v1)->value().rep(), v2.asInt32()) : concatenate(asString(v1)->value().rep(), right); if (UNLIKELY(!value)) { @@ -717,6 +1031,7 @@ DEFINE_STUB_FUNCTION(int, timeout_check) globalData->exception = createInterruptedExecutionException(globalData); VM_THROW_EXCEPTION_AT_END(); } + CHECK_FOR_EXCEPTION_AT_END(); return timeoutChecker->ticksUntilNextCheck(); } @@ -797,25 +1112,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic) DEFINE_STUB_FUNCTION(void, op_put_by_id) { STUB_INIT_STACK_FRAME(stackFrame); - CallFrame* callFrame = stackFrame.callFrame; Identifier& ident = stackFrame.args[1].identifier(); PutPropertySlot slot; stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot); - ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_id_second)); - - CHECK_FOR_EXCEPTION_AT_END(); -} - -DEFINE_STUB_FUNCTION(void, op_put_by_id_second) -{ - STUB_INIT_STACK_FRAME(stackFrame); + CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); + StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); + if (!stubInfo->seenOnce()) + stubInfo->setSeen(); + else + JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo); - PutPropertySlot slot; - stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); - JITThunks::tryCachePutByID(stackFrame.callFrame, stackFrame.callFrame->codeBlock(), STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot); CHECK_FOR_EXCEPTION_AT_END(); } @@ -832,36 +1141,19 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_fail) CHECK_FOR_EXCEPTION_AT_END(); } - -DEFINE_STUB_FUNCTION(EncodedJSValue, op_put_by_id_transition_realloc) +DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc) { STUB_INIT_STACK_FRAME(stackFrame); JSValue baseValue = stackFrame.args[0].jsValue(); - int32_t oldSize = stackFrame.args[1].int32(); - int32_t newSize = stackFrame.args[2].int32(); + int32_t oldSize = stackFrame.args[3].int32(); + int32_t newSize = stackFrame.args[4].int32(); ASSERT(baseValue.isObject()); - asObject(baseValue)->allocatePropertyStorage(oldSize, newSize); - - return JSValue::encode(baseValue); -} - -DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - Identifier& ident = stackFrame.args[1].identifier(); + JSObject* base = asObject(baseValue); + base->allocatePropertyStorage(oldSize, newSize); - JSValue baseValue = stackFrame.args[0].jsValue(); - PropertySlot slot(baseValue); - JSValue result = baseValue.get(callFrame, ident, slot); - - ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_second)); - - CHECK_FOR_EXCEPTION_AT_END(); - return JSValue::encode(result); + return base; } DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) @@ -874,25 +1166,15 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) JSValue baseValue = stackFrame.args[0].jsValue(); PropertySlot slot(baseValue); JSValue result = baseValue.get(callFrame, ident, slot); + CHECK_FOR_EXCEPTION(); - ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_method_check_second)); - - CHECK_FOR_EXCEPTION_AT_END(); - return JSValue::encode(result); -} - -DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - Identifier& ident = stackFrame.args[1].identifier(); - - JSValue baseValue = stackFrame.args[0].jsValue(); - PropertySlot slot(baseValue); - JSValue result = baseValue.get(callFrame, ident, slot); + CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); + MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS); - CHECK_FOR_EXCEPTION(); + if (!methodCallLinkInfo.seenOnce()) { + methodCallLinkInfo.setSeen(); + return JSValue::encode(result); + } // If we successfully got something, then the base from which it is being accessed must // be an object. (Assertion to ensure asObject() call below is safe, which comes after @@ -909,7 +1191,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second) JSObject* slotBaseObject; if (baseValue.isCell() && slot.isCacheable() - && !(structure = asCell(baseValue)->structure())->isDictionary() + && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary() && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific) && specific ) { @@ -923,33 +1205,33 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second) // The result fetched should always be the callee! ASSERT(result == JSValue(callee)); - MethodCallLinkInfo& methodCallLinkInfo = callFrame->codeBlock()->getMethodCallLinkInfo(STUB_RETURN_ADDRESS); // Check to see if the function is on the object's prototype. Patch up the code to optimize. - if (slot.slotBase() == structure->prototypeForLookup(callFrame)) - JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, slotBaseObject); + if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { + JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS); + return JSValue::encode(result); + } + // Check to see if the function is on the object itself. // Since we generate the method-check to check both the structure and a prototype-structure (since this // is the common case) we have a problem - we need to patch the prototype structure check to do something // useful. We could try to nop it out altogether, but that's a little messy, so lets do something simpler // for now. For now it performs a check on a special object on the global object only used for this // purpose. The object is in no way exposed, and as such the check will always pass. - else if (slot.slotBase() == baseValue) - JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy()); - - // For now let any other case be cached as a normal get_by_id. + if (slot.slotBase() == baseValue) { + JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy(), STUB_RETURN_ADDRESS); + return JSValue::encode(result); + } } // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to. - ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id)); - + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id)); return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_second) +DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id) { STUB_INIT_STACK_FRAME(stackFrame); - CallFrame* callFrame = stackFrame.callFrame; Identifier& ident = stackFrame.args[1].identifier(); @@ -957,7 +1239,12 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_second) PropertySlot slot(baseValue); JSValue result = baseValue.get(callFrame, ident, slot); - JITThunks::tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot); + CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); + StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); + if (!stubInfo->seenOnce()) + stubInfo->setSeen(); + else + JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); @@ -978,7 +1265,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (baseValue.isCell() && slot.isCacheable() - && !asCell(baseValue)->structure()->isDictionary() + && !asCell(baseValue)->structure()->isUncacheableDictionary() && slot.slotBase() == baseValue) { CodeBlock* codeBlock = callFrame->codeBlock(); @@ -989,7 +1276,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) PolymorphicAccessStructureList* polymorphicStructureList; int listIndex = 1; - if (stubInfo->opcodeID == op_get_by_id_self) { + if (stubInfo->accessType == access_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); stubInfo->initGetByIdSelfList(polymorphicStructureList, 2); @@ -1013,18 +1300,18 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str PolymorphicAccessStructureList* prototypeStructureList = 0; listIndex = 1; - switch (stubInfo->opcodeID) { - case op_get_by_id_proto: + switch (stubInfo->accessType) { + case access_get_by_id_proto: prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure); stubInfo->stubRoutine = CodeLocationLabel(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; - case op_get_by_id_chain: + case access_get_by_id_chain: prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain); stubInfo->stubRoutine = CodeLocationLabel(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; - case op_get_by_id_proto_list: + case access_get_by_id_proto_list: prototypeStructureList = stubInfo->u.getByIdProtoList.structureList; listIndex = stubInfo->u.getByIdProtoList.listSize; stubInfo->u.getByIdProtoList.listSize++; @@ -1049,7 +1336,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) CHECK_FOR_EXCEPTION(); - if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) { + if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) { ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); return JSValue::encode(result); } @@ -1143,7 +1430,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail) return JSValue::encode(result); } -#endif +#endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof) { @@ -1223,7 +1510,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func) { STUB_INIT_STACK_FRAME(stackFrame); - return stackFrame.args[0].funcDeclNode()->makeFunction(stackFrame.callFrame, stackFrame.callFrame->scopeChain()); + return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain()); } DEFINE_STUB_FUNCTION(void*, op_call_JSFunction) @@ -1237,11 +1524,11 @@ DEFINE_STUB_FUNCTION(void*, op_call_JSFunction) JSFunction* function = asFunction(stackFrame.args[0].jsValue()); ASSERT(!function->isHostFunction()); - FunctionBodyNode* body = function->body(); + FunctionExecutable* executable = function->jsExecutable(); ScopeChainNode* callDataScopeChain = function->scope().node(); - body->jitCode(callDataScopeChain); + executable->jitCode(stackFrame.callFrame, callDataScopeChain); - return &(body->generatedBytecode()); + return function; } DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck) @@ -1249,8 +1536,9 @@ DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - CodeBlock* newCodeBlock = stackFrame.args[3].codeBlock(); - ASSERT(newCodeBlock->codeType() != NativeCode); + JSFunction* callee = asFunction(stackFrame.args[0].jsValue()); + ASSERT(!callee->isHostFunction()); + CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecode(); int argCount = stackFrame.args[2].int32(); ASSERT(argCount != newCodeBlock->m_numParameters); @@ -1287,45 +1575,36 @@ DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck) callFrame->setCallerFrame(oldCallFrame); } - RETURN_POINTER_PAIR(newCodeBlock, callFrame); -} - -DEFINE_STUB_FUNCTION(void*, vm_dontLazyLinkCall) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - JSGlobalData* globalData = stackFrame.globalData; - JSFunction* callee = asFunction(stackFrame.args[0].jsValue()); - - ctiPatchNearCallByReturnAddress(stackFrame.callFrame->callerFrame()->codeBlock(), stackFrame.args[1].returnAddress(), globalData->jitStubs.ctiVirtualCallLink()); - - return callee->body()->generatedJITCode().addressForCall().executableAddress(); + RETURN_POINTER_PAIR(callee, callFrame); } +#if ENABLE(JIT_OPTIMIZE_CALL) DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall) { STUB_INIT_STACK_FRAME(stackFrame); - JSFunction* callee = asFunction(stackFrame.args[0].jsValue()); - JITCode& jitCode = callee->body()->generatedJITCode(); + ExecutableBase* executable = callee->executable(); + JITCode& jitCode = executable->generatedJITCode(); CodeBlock* codeBlock = 0; - if (!callee->isHostFunction()) - codeBlock = &callee->body()->bytecode(callee->scope().node()); - else - codeBlock = &callee->body()->generatedBytecode(); - + if (!executable->isHostFunction()) + codeBlock = &static_cast<FunctionExecutable*>(executable)->bytecode(stackFrame.callFrame, callee->scope().node()); CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress()); - JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData); + + if (!callLinkInfo->seenOnce()) + callLinkInfo->setSeen(); + else + JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData); return jitCode.addressForCall().executableAddress(); } +#endif // !ENABLE(JIT_OPTIMIZE_CALL) DEFINE_STUB_FUNCTION(JSObject*, op_push_activation) { STUB_INIT_STACK_FRAME(stackFrame); - JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionBodyNode*>(stackFrame.callFrame->codeBlock()->ownerNode())); + JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable())); stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->copy()->push(activation)); return activation; } @@ -1385,7 +1664,7 @@ DEFINE_STUB_FUNCTION(void, op_create_arguments) Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame); stackFrame.callFrame->setCalleeArguments(arguments); - stackFrame.callFrame[RegisterFile::ArgumentsRegister] = arguments; + stackFrame.callFrame[RegisterFile::ArgumentsRegister] = JSValue(arguments); } DEFINE_STUB_FUNCTION(void, op_create_arguments_no_params) @@ -1394,7 +1673,7 @@ DEFINE_STUB_FUNCTION(void, op_create_arguments_no_params) Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame, Arguments::NoParameters); stackFrame.callFrame->setCalleeArguments(arguments); - stackFrame.callFrame[RegisterFile::ArgumentsRegister] = arguments; + stackFrame.callFrame[RegisterFile::ArgumentsRegister] = JSValue(arguments); } DEFINE_STUB_FUNCTION(void, op_tear_off_activation) @@ -1550,8 +1829,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) JSValue result; - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSArray(globalData, baseValue)) { JSArray* jsArray = asArray(baseValue); if (jsArray->canGetIndex(i)) @@ -1589,8 +1868,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string) JSValue result; - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) result = asString(baseValue)->getIndex(stackFrame.globalData, i); else { @@ -1607,7 +1886,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string) return JSValue::encode(result); } - DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array) { STUB_INIT_STACK_FRAME(stackFrame); @@ -1620,8 +1898,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array) JSValue result; - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks. return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i)); @@ -1639,50 +1917,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array) return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_func) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - ScopeChainNode* scopeChain = callFrame->scopeChain(); - - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - - // FIXME: add scopeDepthIsZero optimization - - ASSERT(iter != end); - - Identifier& ident = stackFrame.args[0].identifier(); - 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); - CHECK_FOR_EXCEPTION_AT_END(); - - callFrame->registers()[stackFrame.args[1].int32()] = JSValue(thisObj); - return JSValue::encode(result); - } - ++iter; - } while (iter != end); - - CodeBlock* codeBlock = callFrame->codeBlock(); - unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); - stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock); - VM_THROW_EXCEPTION_AT_END(); - return JSValue::encode(JSValue()); -} - DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub) { STUB_INIT_STACK_FRAME(stackFrame); @@ -1712,8 +1946,8 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) JSValue subscript = stackFrame.args[1].jsValue(); JSValue value = stackFrame.args[2].jsValue(); - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSArray(globalData, baseValue)) { JSArray* jsArray = asArray(baseValue); if (jsArray->canSetIndex(i)) @@ -1724,8 +1958,8 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) JSByteArray* jsByteArray = asByteArray(baseValue); ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array)); // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks. - if (value.isInt32Fast()) { - jsByteArray->setIndex(i, value.getInt32Fast()); + if (value.isInt32()) { + jsByteArray->setIndex(i, value.asInt32()); return; } else { double dValue = 0; @@ -1763,14 +1997,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_array) if (LIKELY(i >= 0)) asArray(baseValue)->JSArray::put(callFrame, i, value); else { - // This should work since we're re-boxing an immediate unboxed in JIT code. - ASSERT(JSValue::makeInt32Fast(i)); - Identifier property(callFrame, JSValue::makeInt32Fast(i).toString(callFrame)); - // FIXME: can toString throw an exception here? - if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. - PutPropertySlot slot; - baseValue.put(callFrame, property, value, slot); - } + Identifier property(callFrame, UString::from(i)); + PutPropertySlot slot; + baseValue.put(callFrame, property, value, slot); } CHECK_FOR_EXCEPTION_AT_END(); @@ -1787,14 +2016,14 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) JSValue subscript = stackFrame.args[1].jsValue(); JSValue value = stackFrame.args[2].jsValue(); - if (LIKELY(subscript.isUInt32Fast())) { - uint32_t i = subscript.getUInt32Fast(); + if (LIKELY(subscript.isUInt32())) { + uint32_t i = subscript.asUInt32(); if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { JSByteArray* jsByteArray = asByteArray(baseValue); // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks. - if (value.isInt32Fast()) { - jsByteArray->setIndex(i, value.getInt32Fast()); + if (value.isInt32()) { + jsByteArray->setIndex(i, value.asInt32()); return; } else { double dValue = 0; @@ -1845,6 +2074,7 @@ DEFINE_STUB_FUNCTION(int, op_loop_if_true) DEFINE_STUB_FUNCTION(int, op_load_varargs) { STUB_INIT_STACK_FRAME(stackFrame); + CallFrame* callFrame = stackFrame.callFrame; RegisterFile* registerFile = stackFrame.registerFile; int argsOffset = stackFrame.args[0].int32(); @@ -1859,7 +2089,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) stackFrame.globalData->exception = createStackOverflowError(callFrame); VM_THROW_EXCEPTION(); } - int32_t expectedParams = asFunction(callFrame->registers()[RegisterFile::Callee].jsValue())->body()->parameterCount(); + int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); int32_t inplaceArgs = min(providedParams, expectedParams); Register* inplaceArgsDst = callFrame->registers() + argsOffset; @@ -1991,7 +2221,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - JSGlobalObject* globalObject = asGlobalObject(stackFrame.args[0].jsValue()); + JSGlobalObject* globalObject = stackFrame.args[0].globalObject(); Identifier& ident = stackFrame.args[1].identifier(); unsigned globalResolveInfoIndex = stackFrame.args[2].int32(); ASSERT(globalObject->isGlobalObject()); @@ -1999,7 +2229,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global) PropertySlot slot(globalObject); if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); - if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) { + if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex); if (globalResolveInfo.structure) globalResolveInfo.structure->deref(); @@ -2115,7 +2345,112 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc) return JSValue::encode(number); } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_eq) +#if USE(JSVALUE32_64) + +DEFINE_STUB_FUNCTION(int, op_eq) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + JSValue src1 = stackFrame.args[0].jsValue(); + JSValue src2 = stackFrame.args[1].jsValue(); + + start: + if (src2.isUndefined()) { + return src1.isNull() || + (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) || + src1.isUndefined(); + } + + if (src2.isNull()) { + return src1.isUndefined() || + (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) || + src1.isNull(); + } + + if (src1.isInt32()) { + if (src2.isDouble()) + return src1.asInt32() == src2.asDouble(); + double d = src2.toNumber(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + return src1.asInt32() == d; + } + + if (src1.isDouble()) { + if (src2.isInt32()) + return src1.asDouble() == src2.asInt32(); + double d = src2.toNumber(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + return src1.asDouble() == d; + } + + if (src1.isTrue()) { + if (src2.isFalse()) + return false; + double d = src2.toNumber(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + return d == 1.0; + } + + if (src1.isFalse()) { + if (src2.isTrue()) + return false; + double d = src2.toNumber(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + return d == 0.0; + } + + if (src1.isUndefined()) + return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined(); + + if (src1.isNull()) + return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined(); + + JSCell* cell1 = asCell(src1); + + if (cell1->isString()) { + if (src2.isInt32()) + return static_cast<JSString*>(cell1)->value().toDouble() == src2.asInt32(); + + if (src2.isDouble()) + return static_cast<JSString*>(cell1)->value().toDouble() == src2.asDouble(); + + if (src2.isTrue()) + return static_cast<JSString*>(cell1)->value().toDouble() == 1.0; + + if (src2.isFalse()) + return static_cast<JSString*>(cell1)->value().toDouble() == 0.0; + + JSCell* cell2 = asCell(src2); + if (cell2->isString()) + return static_cast<JSString*>(cell1)->value() == static_cast<JSString*>(cell2)->value(); + + src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + goto start; + } + + if (src2.isObject()) + return asObject(cell1) == asObject(src2); + src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame); + CHECK_FOR_EXCEPTION(); + goto start; +} + +DEFINE_STUB_FUNCTION(int, op_eq_strings) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + JSString* string1 = stackFrame.args[0].jsString(); + JSString* string2 = stackFrame.args[1].jsString(); + + ASSERT(string1->isString()); + ASSERT(string2->isString()); + return string1->value() == string2->value(); +} + +#else // USE(JSVALUE32_64) + +DEFINE_STUB_FUNCTION(int, op_eq) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2124,12 +2459,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_eq) CallFrame* callFrame = stackFrame.callFrame; - ASSERT(!JSValue::areBothInt32Fast(src1, src2)); - JSValue result = jsBoolean(JSValue::equalSlowCaseInline(callFrame, src1, src2)); + bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2); CHECK_FOR_EXCEPTION_AT_END(); - return JSValue::encode(result); + return result; } +#endif // USE(JSVALUE32_64) + DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2137,13 +2473,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift) JSValue val = stackFrame.args[0].jsValue(); JSValue shift = stackFrame.args[1].jsValue(); - int32_t left; - uint32_t right; - if (JSValue::areBothInt32Fast(val, shift)) - return JSValue::encode(jsNumber(stackFrame.globalData, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f))); - if (val.numberToInt32(left) && shift.numberToUInt32(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left << (right & 0x1f))); - CallFrame* callFrame = stackFrame.callFrame; JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION_AT_END(); @@ -2157,11 +2486,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand) JSValue src1 = stackFrame.args[0].jsValue(); JSValue src2 = stackFrame.args[1].jsValue(); - int32_t left; - int32_t right; - if (src1.numberToInt32(left) && src2.numberToInt32(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left & right)); - + ASSERT(!src1.isInt32() || !src2.isInt32()); CallFrame* callFrame = stackFrame.callFrame; JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); @@ -2175,15 +2500,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift) JSValue val = stackFrame.args[0].jsValue(); JSValue shift = stackFrame.args[1].jsValue(); - int32_t left; - uint32_t right; - if (JSFastMath::canDoFastRshift(val, shift)) - return JSValue::encode(JSFastMath::rightShiftImmediateNumbers(val, shift)); - if (val.numberToInt32(left) && shift.numberToUInt32(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left >> (right & 0x1f))); - CallFrame* callFrame = stackFrame.callFrame; JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); + CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2194,10 +2513,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot) JSValue src = stackFrame.args[0].jsValue(); - int value; - if (src.numberToInt32(value)) - return JSValue::encode(jsNumber(stackFrame.globalData, ~value)); - + ASSERT(!src.isInt32()); CallFrame* callFrame = stackFrame.callFrame; JSValue result = jsNumber(stackFrame.globalData, ~src.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); @@ -2243,8 +2559,24 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base) DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp) { STUB_INIT_STACK_FRAME(stackFrame); + CallFrame* callFrame = stackFrame.callFrame; + + FunctionExecutable* function = stackFrame.args[0].function(); + JSFunction* func = function->make(callFrame, callFrame->scopeChain()); + + /* + The Identifier in a FunctionExpression can be referenced from inside + the FunctionExpression's FunctionBody to allow the function to call + itself recursively. However, unlike in a FunctionDeclaration, the + Identifier in a FunctionExpression cannot be referenced from and + does not affect the scope enclosing the FunctionExpression. + */ + if (!function->name().isNull()) { + JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); + func->scope().push(functionScopeObject); + } - return stackFrame.args[0].funcExprNode()->makeFunction(stackFrame.callFrame, stackFrame.callFrame->scopeChain()); + return func; } DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod) @@ -2271,21 +2603,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_less) return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_neq) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - JSValue src1 = stackFrame.args[0].jsValue(); - JSValue src2 = stackFrame.args[1].jsValue(); - - ASSERT(!JSValue::areBothInt32Fast(src1, src2)); - - CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsBoolean(!JSValue::equalSlowCaseInline(callFrame, src1, src2)); - CHECK_FOR_EXCEPTION_AT_END(); - return JSValue::encode(result); -} - DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2309,14 +2626,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift) JSValue shift = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - - if (JSFastMath::canDoFastUrshift(val, shift)) - return JSValue::encode(JSFastMath::rightShiftImmediateNumbers(val, shift)); - else { - JSValue result = jsNumber(stackFrame.globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); - CHECK_FOR_EXCEPTION_AT_END(); - return JSValue::encode(result); - } + JSValue result = jsNumber(stackFrame.globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); + CHECK_FOR_EXCEPTION_AT_END(); + return JSValue::encode(result); } DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor) @@ -2375,7 +2687,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval) if (thisValue == globalObject && funcVal == globalObject->evalFunction()) { JSValue exceptionValue; JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue); - if (UNLIKELY(exceptionValue != JSValue())) { + if (UNLIKELY(exceptionValue)) { stackFrame.globalData->exception = exceptionValue; VM_THROW_EXCEPTION_AT_END(); } @@ -2613,8 +2925,8 @@ DEFINE_STUB_FUNCTION(void*, op_switch_imm) CallFrame* callFrame = stackFrame.callFrame; CodeBlock* codeBlock = callFrame->codeBlock(); - if (scrutinee.isInt32Fast()) - return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast()).executableAddress(); + if (scrutinee.isInt32()) + return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress(); else { double value; int32_t intValue; @@ -2724,7 +3036,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_error) unsigned bytecodeOffset = stackFrame.args[2].int32(); unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset); - return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); } DEFINE_STUB_FUNCTION(void, op_debug) @@ -2749,7 +3061,7 @@ DEFINE_STUB_FUNCTION(void, op_debug_catch) if (JSC::Debugger* debugger = callFrame->lexicalGlobalObject()->debugger() ) { JSValue exceptionValue = callFrame->r(stackFrame.args[0].int32()).jsValue(); DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); - debugger->exceptionCatch(debuggerCallFrame, callFrame->codeBlock()->ownerNode()->sourceID()); + debugger->exceptionCatch(debuggerCallFrame, callFrame->codeBlock()->source()->asID()); } } @@ -2759,7 +3071,7 @@ DEFINE_STUB_FUNCTION(void, op_debug_return) CallFrame* callFrame = stackFrame.callFrame; if (JSC::Debugger* debugger = callFrame->lexicalGlobalObject()->debugger() ) { JSValue returnValue = callFrame->r(stackFrame.args[0].int32()).jsValue(); - intptr_t sourceID = callFrame->codeBlock()->ownerNode()->sourceID(); + intptr_t sourceID = callFrame->codeBlock()->source()->asID(); debugger->functionExit(returnValue, sourceID); } } @@ -2794,8 +3106,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw) return JSValue::encode(exceptionValue); } -} // namespace JITStubs - } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h index 325c3fd..3ae8f24 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h @@ -38,8 +38,11 @@ namespace JSC { + struct StructureStubInfo; + class CodeBlock; class ExecutablePool; + class FunctionExecutable; class Identifier; class JSGlobalData; class JSGlobalData; @@ -51,8 +54,7 @@ namespace JSC { class PropertySlot; class PutPropertySlot; class RegisterFile; - class FuncDeclNode; - class FuncExprNode; + class JSGlobalObject; class RegExp; union JITStubArg { @@ -64,17 +66,26 @@ namespace JSC { Identifier& identifier() { return *static_cast<Identifier*>(asPointer); } int32_t int32() { return asInt32; } CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); } - FuncDeclNode* funcDeclNode() { return static_cast<FuncDeclNode*>(asPointer); } - FuncExprNode* funcExprNode() { return static_cast<FuncExprNode*>(asPointer); } + FunctionExecutable* function() { return static_cast<FunctionExecutable*>(asPointer); } RegExp* regExp() { return static_cast<RegExp*>(asPointer); } JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); } + JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); } + JSString* jsString() { return static_cast<JSString*>(asPointer); } ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); } }; #if PLATFORM(X86_64) struct JITStackFrame { - JITStubArg padding; // Unused - JITStubArg args[8]; + void* reserved; // Unused + JITStubArg args[6]; + void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill). + + void* code; + RegisterFile* registerFile; + CallFrame* callFrame; + JSValue* exception; + Profiler** enabledProfilerReference; + JSGlobalData* globalData; void* savedRBX; void* savedR15; @@ -84,20 +95,20 @@ namespace JSC { void* savedRBP; void* savedRIP; - void* code; - RegisterFile* registerFile; - CallFrame* callFrame; - JSValue* exception; - 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; } }; #elif PLATFORM(X86) +#if COMPILER(MSVC) +#pragma pack(push) +#pragma pack(4) +#endif // COMPILER(MSVC) struct JITStackFrame { - JITStubArg padding; // Unused + void* reserved; // Unused JITStubArg args[6]; +#if USE(JSVALUE32_64) + void* padding[2]; // Maintain 16-byte stack alignment. +#endif void* savedEBX; void* savedEDI; @@ -115,10 +126,16 @@ namespace JSC { // 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; } }; -#elif PLATFORM_ARM_ARCH(7) +#if COMPILER(MSVC) +#pragma pack(pop) +#endif // COMPILER(MSVC) +#elif PLATFORM(ARM_THUMB2) struct JITStackFrame { - JITStubArg padding; // Unused + void* reserved; // Unused JITStubArg args[6]; +#if USE(JSVALUE32_64) + void* padding[2]; // Maintain 16-byte stack alignment. +#endif ReturnAddressPtr thunkReturnAddress; @@ -132,12 +149,35 @@ namespace JSC { CallFrame* callFrame; JSValue* exception; + void* padding2; + // These arguments passed on the stack. Profiler** enabledProfilerReference; JSGlobalData* globalData; ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; +#elif PLATFORM(ARM_TRADITIONAL) + struct JITStackFrame { + JITStubArg padding; // Unused + JITStubArg args[7]; + + void* preservedR4; + void* preservedR5; + void* preservedR6; + void* preservedR7; + void* preservedR8; + void* preservedLink; + + RegisterFile* registerFile; + CallFrame* callFrame; + JSValue* exception; + 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; } + }; #else #error "JITStackFrame not defined for this platform." #endif @@ -183,24 +223,16 @@ namespace JSC { extern "C" void ctiVMThrowTrampoline(); extern "C" void ctiOpThrowNotCaught(); - extern "C" EncodedJSValue ctiTrampoline( -#if PLATFORM(X86_64) - // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect). - // We can allow register passing here, and move the writes of these values into the trampoline. - void*, void*, void*, void*, void*, void*, -#endif - void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*); + extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*); class JITThunks { public: JITThunks(JSGlobalData*); - static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&); - static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&); - - MacroAssemblerCodePtr ctiArrayLengthTrampoline() { return m_ctiArrayLengthTrampoline; } + static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo); + static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo); + MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; } - MacroAssemblerCodePtr ctiVirtualCallPreLink() { return m_ctiVirtualCallPreLink; } MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; } MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; } MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; } @@ -208,68 +240,13 @@ namespace JSC { private: RefPtr<ExecutablePool> m_executablePool; - MacroAssemblerCodePtr m_ctiArrayLengthTrampoline; MacroAssemblerCodePtr m_ctiStringLengthTrampoline; - MacroAssemblerCodePtr m_ctiVirtualCallPreLink; MacroAssemblerCodePtr m_ctiVirtualCallLink; MacroAssemblerCodePtr m_ctiVirtualCall; MacroAssemblerCodePtr m_ctiNativeCallThunk; }; -namespace JITStubs { extern "C" { - - 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); -#ifdef QT_BUILD_SCRIPT_LIB - void JIT_STUB cti_op_debug_catch(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_debug_return(STUB_ARGS_DECLARATION); -#endif - void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_second(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); - void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION); - void JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_loop_if_less(STUB_ARGS_DECLARATION); - 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); - void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION); - JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION); +extern "C" { EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_bitnot(STUB_ARGS_DECLARATION); @@ -278,25 +255,22 @@ namespace JITStubs { extern "C" { EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_method_check_second(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_second(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION); @@ -311,16 +285,18 @@ namespace JITStubs { 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_neq(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); + EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION); @@ -331,13 +307,62 @@ namespace JITStubs { 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_op_post_dec(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_func(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_with_base(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); + JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION); + JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION); + JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION); VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION); - -}; } // extern "C" namespace JITStubs + int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION); +#if USE(JSVALUE32_64) + int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION); +#endif + int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION); + int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION); + int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION); + int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION); + int JIT_STUB cti_op_loop_if_less(STUB_ARGS_DECLARATION); + 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); + 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); +#ifdef QT_BUILD_SCRIPT_LIB + void JIT_STUB cti_op_debug_catch(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_debug_return(STUB_ARGS_DECLARATION); +#endif + void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION); + 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); + void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION); + void JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION); +} // extern "C" } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp index 190deff..92b1e58 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp @@ -443,14 +443,12 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr return success; } -static -#if !HAVE(READLINE) -NO_RETURN -#endif -void runInteractive(GlobalObject* globalObject) +#define RUNNING_FROM_XCODE 0 + +static void runInteractive(GlobalObject* globalObject) { while (true) { -#if HAVE(READLINE) +#if HAVE(READLINE) && !RUNNING_FROM_XCODE char* line = readline(interactivePrompt); if (!line) break; @@ -459,7 +457,7 @@ void runInteractive(GlobalObject* globalObject) Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName)); free(line); #else - puts(interactivePrompt); + printf("%s", interactivePrompt); Vector<char, 256> line; int c; while ((c = getchar()) != EOF) { @@ -468,6 +466,8 @@ void runInteractive(GlobalObject* globalObject) break; line.append(c); } + if (line.isEmpty()) + break; line.append('\0'); Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName)); #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdbool.h b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdbool.h index 8e7bace..fc8ee28 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdbool.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdbool.h @@ -21,8 +21,8 @@ #ifndef STDBOOL_WIN32_H #define STDBOOL_WIN32_H -#if !PLATFORM(WIN_OS) -#error "This stdbool.h file should only be compiled under Windows" +#if !COMPILER(MSVC) +#error "This stdbool.h file should only be compiled with MSVC" #endif #ifndef __cplusplus diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdint.h b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdint.h index efab2ae..1d8787e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdint.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/stdint.h @@ -23,10 +23,11 @@ #include <wtf/Platform.h> -/* This file emulates enough of stdint.h on Windows to make JavaScriptCore and WebCore compile. */ +/* This file emulates enough of stdint.h on Windows to make JavaScriptCore and WebCore + compile using MSVC which does not ship with the stdint.h header. */ -#if !PLATFORM(WIN_OS) -#error "This stdint.h file should only be compiled under Windows" +#if !COMPILER(MSVC) +#error "This stdint.h file should only be compiled with MSVC" #endif #include <limits.h> diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.cpp deleted file mode 100644 index 92efae0..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.cpp +++ /dev/null @@ -1,677 +0,0 @@ -// -// strftime.c -// -// Date to string conversion -// -// Copyright (C) 2002 Michael Ringgaard. 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. -// 3. Neither the name of the project nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. -// - -///////////////////////////////////////////////////////////////////////////////////////////// -// // -// time() // -// // -///////////////////////////////////////////////////////////////////////////////////////////// - - -#include <windows.h> -#include <time.h> -#include "ce_time.h" - -time_t -time(time_t* timer) -{ - SYSTEMTIME systime; - struct tm tmtime; - time_t tt; - - GetLocalTime(&systime); - - tmtime.tm_year = systime.wYear-1900; - tmtime.tm_mon = systime.wMonth-1; - tmtime.tm_mday = systime.wDay; - tmtime.tm_wday = systime.wDayOfWeek; - tmtime.tm_hour = systime.wHour; - tmtime.tm_min = systime.wMinute; - tmtime.tm_sec = systime.wSecond; - - tt = mktime(&tmtime); - - if(timer) - *timer = tt; - - return tt; -} - - -///////////////////////////////////////////////////////////////////////////////////////////// -// // -// mktime() // -// // -///////////////////////////////////////////////////////////////////////////////////////////// - -static int month_to_day[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - -time_t mktime(struct tm *t) -{ - short month, year; - time_t result; - - month = t->tm_mon; - year = t->tm_year + month / 12 + 1900; - month %= 12; - if (month < 0) - { - year -= 1; - month += 12; - } - result = (year - 1970) * 365 + (year - 1969) / 4 + month_to_day[month]; - result = (year - 1970) * 365 + month_to_day[month]; - if (month <= 1) - year -= 1; - result += (year - 1968) / 4; - result -= (year - 1900) / 100; - result += (year - 1600) / 400; - result += t->tm_mday; - result -= 1; - result *= 24; - result += t->tm_hour; - result *= 60; - result += t->tm_min; - result *= 60; - result += t->tm_sec; - return(result); -} - - -///////////////////////////////////////////////////////////////////////////////////////////// -// // -// strftime() - taken from OpenBSD // -// // -///////////////////////////////////////////////////////////////////////////////////////////// - -#define IN_NONE 0 -#define IN_SOME 1 -#define IN_THIS 2 -#define IN_ALL 3 -#define CHAR_BIT 8 - -#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) -#define TYPE_SIGNED(type) (((type) -1) < 0) - -#define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) - -#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) - -#define MONSPERYEAR 12 -#define DAYSPERWEEK 7 -#define TM_YEAR_BASE 1900 -#define HOURSPERDAY 24 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 - -static char wildabbr[] = "WILDABBR"; - -static char * tzname[2] = { - wildabbr, - wildabbr -}; - - -#define Locale (&C_time_locale) - -struct lc_time_T { - const char * mon[MONSPERYEAR]; - const char * month[MONSPERYEAR]; - const char * wday[DAYSPERWEEK]; - const char * weekday[DAYSPERWEEK]; - const char * X_fmt; - const char * x_fmt; - const char * c_fmt; - const char * am; - const char * pm; - const char * date_fmt; -}; - -static const struct lc_time_T C_time_locale = { - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, { - "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" - }, { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }, - - /* X_fmt */ - "%H:%M:%S", - - /* - ** x_fmt - ** C99 requires this format. - ** Using just numbers (as here) makes Quakers happier; - ** it's also compatible with SVR4. - */ - "%m/%d/%y", - - /* - ** c_fmt - ** C99 requires this format. - ** Previously this code used "%D %X", but we now conform to C99. - ** Note that - ** "%a %b %d %H:%M:%S %Y" - ** is used by Solaris 2.3. - */ - "%a %b %e %T %Y", - - /* am */ - "AM", - - /* pm */ - "PM", - - /* date_fmt */ - "%a %b %e %H:%M:%S %Z %Y" -}; - - -static char * -_add(const char * str, char * pt, const char * const ptlim) -{ - while (pt < ptlim && (*pt = *str++) != '\0') - ++pt; - return pt; -} - - -static char * -_conv(const int n, const char * const format, char * const pt, const char * const ptlim) -{ - char buf[INT_STRLEN_MAXIMUM(int) + 1]; - - (void) _snprintf(buf, sizeof buf, format, n); - return _add(buf, pt, ptlim); -} - - -static char * -_fmt(const char * format, const struct tm * const t, char * pt, const char * const ptlim, int * warnp) -{ - for ( ; *format; ++format) { - if (*format == '%') { -label: - switch (*++format) { - case '\0': - --format; - break; - case 'A': - pt = _add((t->tm_wday < 0 || - t->tm_wday >= DAYSPERWEEK) ? - "?" : Locale->weekday[t->tm_wday], - pt, ptlim); - continue; - case 'a': - pt = _add((t->tm_wday < 0 || - t->tm_wday >= DAYSPERWEEK) ? - "?" : Locale->wday[t->tm_wday], - pt, ptlim); - continue; - case 'B': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? - "?" : Locale->month[t->tm_mon], - pt, ptlim); - continue; - case 'b': - case 'h': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? - "?" : Locale->mon[t->tm_mon], - pt, ptlim); - continue; - case 'C': - /* - ** %C used to do a... - ** _fmt("%a %b %e %X %Y", t); - ** ...whereas now POSIX 1003.2 calls for - ** something completely different. - ** (ado, 1993-05-24) - */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - "%02d", pt, ptlim); - continue; - case 'c': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } - continue; - case 'D': - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); - continue; - case 'd': - pt = _conv(t->tm_mday, "%02d", pt, ptlim); - continue; - case 'E': - case 'O': - /* - ** C99 locale modifiers. - ** The sequences - ** %Ec %EC %Ex %EX %Ey %EY - ** %Od %oe %OH %OI %Om %OM - ** %OS %Ou %OU %OV %Ow %OW %Oy - ** are supposed to provide alternate - ** representations. - */ - goto label; - case 'e': - pt = _conv(t->tm_mday, "%2d", pt, ptlim); - continue; - case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); - continue; - case 'H': - pt = _conv(t->tm_hour, "%02d", pt, ptlim); - continue; - case 'I': - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - "%02d", pt, ptlim); - continue; - case 'j': - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); - continue; - case 'k': - /* - ** This used to be... - ** _conv(t->tm_hour % 12 ? - ** t->tm_hour % 12 : 12, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 1993-05-24) - */ - pt = _conv(t->tm_hour, "%2d", pt, ptlim); - continue; -#ifdef KITCHEN_SINK - case 'K': - /* - ** After all this time, still unclaimed! - */ - pt = _add("kitchen sink", pt, ptlim); - continue; -#endif /* defined KITCHEN_SINK */ - case 'l': - /* - ** This used to be... - ** _conv(t->tm_hour, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 1993-05-24) - */ - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - "%2d", pt, ptlim); - continue; - case 'M': - pt = _conv(t->tm_min, "%02d", pt, ptlim); - continue; - case 'm': - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); - continue; - case 'n': - pt = _add("\n", pt, ptlim); - continue; - case 'p': - pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? - Locale->pm : - Locale->am, - pt, ptlim); - continue; - case 'R': - pt = _fmt("%H:%M", t, pt, ptlim, warnp); - continue; - case 'r': - pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp); - continue; - case 'S': - pt = _conv(t->tm_sec, "%02d", pt, ptlim); - continue; - case 's': - { - struct tm tm; - char buf[INT_STRLEN_MAXIMUM( - time_t) + 1]; - time_t mkt; - - tm = *t; - mkt = mktime(&tm); - if (TYPE_SIGNED(time_t)) - (void) _snprintf(buf, sizeof buf, - "%ld", (long) mkt); - else (void) _snprintf(buf, sizeof buf, - "%lu", (unsigned long) mkt); - pt = _add(buf, pt, ptlim); - } - continue; - case 'T': - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); - continue; - case 't': - pt = _add("\t", pt, ptlim); - continue; - case 'U': - pt = _conv((t->tm_yday + DAYSPERWEEK - - t->tm_wday) / DAYSPERWEEK, - "%02d", pt, ptlim); - continue; - case 'u': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "ISO 8601: Weekday as a decimal number - ** [1 (Monday) - 7]" - ** (ado, 1993-05-24) - */ - pt = _conv((t->tm_wday == 0) ? - DAYSPERWEEK : t->tm_wday, - "%d", pt, ptlim); - continue; - case 'V': /* ISO 8601 week number */ - case 'G': /* ISO 8601 year (four digits) */ - case 'g': /* ISO 8601 year (two digits) */ - { - int year; - int yday; - int wday; - int w; - - year = t->tm_year + TM_YEAR_BASE; - yday = t->tm_yday; - wday = t->tm_wday; - for ( ; ; ) { - int len; - int bot; - int top; - - len = isleap(year) ? - DAYSPERLYEAR : - DAYSPERNYEAR; - /* - ** What yday (-3 ... 3) does - ** the ISO year begin on? - */ - bot = ((yday + 11 - wday) % - DAYSPERWEEK) - 3; - /* - ** What yday does the NEXT - ** ISO year begin on? - */ - top = bot - - (len % DAYSPERWEEK); - if (top < -3) - top += DAYSPERWEEK; - top += len; - if (yday >= top) { - ++year; - w = 1; - break; - } - if (yday >= bot) { - w = 1 + ((yday - bot) / - DAYSPERWEEK); - break; - } - --year; - yday += isleap(year) ? - DAYSPERLYEAR : - DAYSPERNYEAR; - } - if (*format == 'V') - pt = _conv(w, "%02d", - pt, ptlim); - else if (*format == 'g') { - *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", - pt, ptlim); - } else pt = _conv(year, "%04d", - pt, ptlim); - } - continue; - case 'v': - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); - continue; - case 'W': - pt = _conv((t->tm_yday + DAYSPERWEEK - - (t->tm_wday ? - (t->tm_wday - 1) : - (DAYSPERWEEK - 1))) / DAYSPERWEEK, - "%02d", pt, ptlim); - continue; - case 'w': - pt = _conv(t->tm_wday, "%d", pt, ptlim); - continue; - case 'X': - pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp); - continue; - case 'x': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } - continue; - case 'y': - *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - "%02d", pt, ptlim); - continue; - case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", - pt, ptlim); - continue; - case 'Z': - if (t->tm_isdst >= 0) - pt = _add(tzname[t->tm_isdst != 0], - pt, ptlim); - /* - ** C99 says that %Z must be replaced by the - ** empty string if the time zone is not - ** determinable. - */ - continue; - case 'z': - { - int diff; - char const * sign; - - if (t->tm_isdst < 0) - continue; - continue; - if (diff < 0) { - sign = "-"; - diff = -diff; - } else sign = "+"; - pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, - "%04d", pt, ptlim); - } - continue; - case '+': - pt = _fmt(Locale->date_fmt, t, pt, ptlim, - warnp); - continue; - case '%': - default: - break; - } - } - if (pt == ptlim) - break; - *pt++ = *format; - } - return pt; -} - - -size_t -strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t) -{ - char * p; - int warn; - - //tzset(); - - warn = IN_NONE; - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn); - - if (p == s + maxsize) { - if (maxsize > 0) - s[maxsize - 1] = '\0'; - return 0; - } - *p = '\0'; - return p - s; -} - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// // -// gmtime() // -// // -///////////////////////////////////////////////////////////////////////////////////////////// - - - -static struct tm mytm; - -static int DMonth[13] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 }; -static int monthCodes[12] = { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; - - -static int -calcDayOfWeek(const struct tm* nTM) -{ - int day; - - day = (nTM->tm_year%100); - day += day/4; - day += monthCodes[nTM->tm_mon]; - day += nTM->tm_mday; - while(day>=7) - day -= 7; - - return day; -} - - -static struct tm * -gmtime(const time_t *timer) -{ - unsigned long x = *timer; - int imin, ihrs, iday, iyrs; - int sec, min, hrs, day, mon, yrs; - int lday, qday, jday, mday; - - - imin = x / 60; // whole minutes since 1/1/70 - sec = x - (60 * imin); // leftover seconds - ihrs = imin / 60; // whole hours since 1/1/70 - min = imin - 60 * ihrs; // leftover minutes - iday = ihrs / 24; // whole days since 1/1/70 - hrs = ihrs - 24 * iday; // leftover hours - iday = iday + 365 + 366; // whole days since 1/1/68 - lday = iday / (( 4* 365) + 1); // quadyr = 4 yr period = 1461 days - qday = iday % (( 4 * 365) + 1); // days since current quadyr began - if(qday >= (31 + 29)) // if past feb 29 then - lday = lday + 1; // add this quadyr’s leap day to the - // # of quadyrs (leap days) since 68 - iyrs = (iday - lday) / 365; // whole years since 1968 - jday = iday - (iyrs * 365) - lday; // days since 1 /1 of current year. - if(qday <= 365 && qday >= 60) // if past 2/29 and a leap year then - jday = jday + 1; // add a leap day to the # of whole - // days since 1/1 of current year - yrs = iyrs + 1968; // compute year - mon = 13; // estimate month ( +1) - mday = 366; // max days since 1/1 is 365 - while(jday < mday) // mday = # of days passed from 1/1 - { // until first day of current month - mon = mon - 1; // mon = month (estimated) - mday = DMonth[mon]; // # elapsed days at first of ”mon” - if((mon > 2) && (yrs % 4) == 0) // if past 2/29 and leap year then - mday = mday + 1; // add leap day - // compute month by decrementing - } // month until found - - day = jday - mday + 1; // compute day of month - - mytm.tm_sec = sec; - mytm.tm_min = min; - mytm.tm_hour = hrs; - mytm.tm_mday = day; - mytm.tm_mon = mon; - mytm.tm_year = yrs - 1900; - - mytm.tm_wday = calcDayOfWeek(&mytm); - mytm.tm_yday = jday; - mytm.tm_isdst = 0; - - return &mytm; -} - - -///////////////////////////////////////////////////////////////////////////////////////////// -// // -// localtime() - simply using gmtime() // -// // -///////////////////////////////////////////////////////////////////////////////////////////// - - -struct tm * -localtime(const time_t *timer) -{ - return gmtime(timer); -} diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.h b/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.h deleted file mode 100644 index 9d946e8..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/os-wince/ce_time.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __CE_TIME_H__ -#define __CE_TIME_H__ - -#if defined(_WIN32_WCE) && _WIN32_WCE >= 0x600 -// we need to prototype the time functions for Windows CE >= 6.0 -#include <crtdefs.h> - -struct tm; - -time_t time(time_t* timer); -time_t mktime(struct tm *t); -size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); -struct tm *localtime(const time_t *timer); -#endif - -#endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y index a3bf1fe..ffed3bb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y @@ -25,18 +25,12 @@ #include "config.h" -#include <string.h> -#include <stdlib.h> -#include "JSValue.h" #include "JSObject.h" -#include "NodeConstructors.h" -#include "Lexer.h" #include "JSString.h" -#include "JSGlobalData.h" -#include "CommonIdentifiers.h" +#include "NodeConstructors.h" #include "NodeInfo.h" -#include "Parser.h" -#include <wtf/FastMalloc.h> +#include <stdlib.h> +#include <string.h> #include <wtf/MathExtras.h> #define YYMALLOC fastMalloc @@ -45,46 +39,44 @@ #define YYMAXDEPTH 10000 #define YYENABLE_NLS 0 -/* default values for bison */ +// Default values for bison. #define YYDEBUG 0 // Set to 1 to debug a parse error. #define jscyydebug 0 // Set to 1 to debug a parse error. #if !PLATFORM(DARWIN) - // avoid triggering warnings in older bison +// Avoid triggering warnings in older bison by not setting this on the Darwin platform. +// FIXME: Is this still needed? #define YYERROR_VERBOSE #endif int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); + static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); #define GLOBAL_DATA static_cast<JSGlobalData*>(globalPtr) -#define LEXER (GLOBAL_DATA->lexer) - -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0) -#define SET_EXCEPTION_LOCATION(node, start, divot, end) node->setExceptionSourceCode((divot), (divot) - (start), (end) - (divot)) -#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line, (s).first_column + 1) +#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*GLOBAL_DATA->lexer, yychar)) YYABORT; } while (0) using namespace JSC; using namespace std; -static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end); -static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static PropertyNode* makeGetterOrSetterPropertyNode(void*, const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); -static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end); -static ExpressionNode* makeTypeOfNode(void*, ExpressionNode*); -static ExpressionNode* makeDeleteNode(void*, ExpressionNode*, int start, int divot, int end); -static ExpressionNode* makeNegateNode(void*, ExpressionNode*); -static NumberNode* makeNumberNode(void*, double); -static ExpressionNode* makeBitwiseNotNode(void*, ExpressionNode*); -static ExpressionNode* makeMultNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeDivNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeAddNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static StatementNode* makeVarStatementNode(void*, ExpressionNode*); -static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, ExpressionNode* init); +static ExpressionNode* makeAssignNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end); +static ExpressionNode* makePrefixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static ExpressionNode* makePostfixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData*, const Identifier& getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData*, ExpressionNodeInfo function, ArgumentsNodeInfo, int start, int divot, int end); +static ExpressionNode* makeTypeOfNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeDeleteNode(JSGlobalData*, ExpressionNode*, int start, int divot, int end); +static ExpressionNode* makeNegateNode(JSGlobalData*, ExpressionNode*); +static NumberNode* makeNumberNode(JSGlobalData*, double); +static ExpressionNode* makeBitwiseNotNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeMultNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeDivNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeAddNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeSubNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeLeftShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeRightShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static StatementNode* makeVarStatementNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* combineCommaNodes(JSGlobalData*, ExpressionNode* list, ExpressionNode* init); #if COMPILER(MSVC) @@ -97,17 +89,17 @@ static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, Expression #define YYPARSE_PARAM globalPtr #define YYLEX_PARAM globalPtr -template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserArenaData<DeclarationStacks::VarStack>* varDecls, - ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, - CodeFeatures info, - int numConstants) +template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, + ParserArenaData<DeclarationStacks::VarStack>* varDecls, + ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, + CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeDeclarationInfo<T> result = { node, varDecls, funcDecls, info, numConstants }; return result; } -template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) +template <typename T> inline NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeInfo<T> result = { node, info, numConstants }; @@ -133,21 +125,20 @@ template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) return decls1; } -static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) { if (!varDecls) - varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - - varDecls->data.append(make_pair(ident, attrs)); + varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>; + varDecls->data.append(make_pair(&ident, attrs)); } -static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) { unsigned attrs = DeclarationStacks::IsConstant; if (decl->hasInitializer()) attrs |= DeclarationStacks::HasInitializer; - appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs); + appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs); } %} @@ -155,7 +146,7 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<D %union { int intValue; double doubleValue; - Identifier* ident; + const Identifier* ident; // expression subtrees ExpressionNodeInfo expressionNode; @@ -184,6 +175,20 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<D Operator op; } +%{ + +template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end) +{ + statement->setLoc(start.first_line, end.last_line, start.first_column + 1); +} + +static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end) +{ + node->setExceptionSourceCode(divot, divot - start, end - divot); +} + +%} + %start Program /* literals */ @@ -291,21 +296,25 @@ Literal: | NUMBER { $$ = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, $1), 0, 1); } | STRING { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *$1), 0, 1); } | '/' /* regexp */ { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags)) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } | DIVEQUAL /* regexp with /= */ { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags, '=')) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } ; @@ -313,14 +322,14 @@ Literal: Property: IDENT ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } | STRING ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | NUMBER ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, 0, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; } + | NUMBER ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, $1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } + | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, 0, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); if (!$$.m_node) YYABORT; } | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { - $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); + $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, $4.m_node.head, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - DBG($7, @6, @8); + setStatementLocation($7, @6, @8); if (!$$.m_node) YYABORT; } @@ -385,15 +394,15 @@ MemberExpr: PrimaryExpr | FunctionExpr { $$ = createNodeInfo<ExpressionNode*>($1.m_node, $1.m_features, $1.m_numConstants); } | MemberExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | MemberExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); } ; @@ -401,15 +410,15 @@ MemberExpr: MemberExprNoBF: PrimaryExprNoBrace | MemberExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | MemberExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); } ; @@ -417,7 +426,7 @@ MemberExprNoBF: NewExpr: MemberExpr | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; @@ -425,32 +434,32 @@ NewExpr: NewExprNoBF: MemberExprNoBF | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; CallExpr: - MemberExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + MemberExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } | CallExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | CallExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; CallExprNoBF: - MemberExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + MemberExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } | CallExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | CallExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; @@ -568,10 +577,10 @@ RelationalExpr: | RelationalExpr LE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr INTOKEN ShiftExpr { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -583,7 +592,7 @@ RelationalExprNoIn: | RelationalExprNoIn GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoIn INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -595,11 +604,11 @@ RelationalExprNoBF: | RelationalExprNoBF GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoBF INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoBF INTOKEN ShiftExpr { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -810,17 +819,17 @@ Statement: ; Block: - OPENBRACE CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } - | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + OPENBRACE CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); + setStatementLocation($$.m_node, @1, @2); } + | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); + setStatementLocation($$.m_node, @1, @3); } ; VariableStatement: VAR VariableDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | VAR VariableDeclarationList error { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @2); + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; @@ -833,7 +842,7 @@ VariableDeclarationList: $$.m_numConstants = 0; } | IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); $$.m_node = node; $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -851,7 +860,7 @@ VariableDeclarationList: } | VariableDeclarationList ',' IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -870,7 +879,7 @@ VariableDeclarationListNoIn: $$.m_numConstants = 0; } | IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); $$.m_node = node; $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -888,7 +897,7 @@ VariableDeclarationListNoIn: } | VariableDeclarationListNoIn ',' IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -900,10 +909,10 @@ VariableDeclarationListNoIn: ConstStatement: CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | CONSTTOKEN ConstDeclarationList error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ConstDeclarationList: @@ -945,36 +954,36 @@ EmptyStatement: ExprStatement: ExprNoBF ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | ExprNoBF error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } ; IfStatement: IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } | IF '(' Expr ')' Statement ELSE Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations), $3.m_features | $5.m_features | $7.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; IterationStatement: DO Statement WHILE '(' Expr ')' ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | DO Statement WHILE '(' Expr ')' error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. + setStatementLocation($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. | WHILE '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations, $3.m_features | $5.m_features | $7.m_features | $9.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @8); + setStatementLocation($$.m_node, @1, @8); } | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $4.m_node, $6.m_node, $8.m_node, $10.m_node, true), @@ -982,30 +991,30 @@ IterationStatement: mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations), $4.m_features | $6.m_features | $8.m_features | $10.m_features, $4.m_numConstants + $6.m_numConstants + $8.m_numConstants + $10.m_numConstants); - DBG($$.m_node, @1, @9); } + setStatementLocation($$.m_node, @1, @9); } | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement { ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node); - SET_EXCEPTION_LOCATION(node, @3.first_column, @3.last_column, @5.last_column); + setExceptionLocation(node, @3.first_column, @3.last_column, @5.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, $7.m_varDeclarations, $7.m_funcDeclarations, $3.m_features | $5.m_features | $7.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @6); + setStatementLocation($$.m_node, @1, @6); } | FOR '(' VAR IDENT INTOKEN Expr ')' Statement { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column); - SET_EXCEPTION_LOCATION(forIn, @4.first_column, @5.first_column + 1, @6.last_column); + setExceptionLocation(forIn, @4.first_column, @5.first_column + 1, @6.last_column); appendToVarDeclarationList(GLOBAL_DATA, $8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $6.m_features | $8.m_features, $6.m_numConstants + $8.m_numConstants); - DBG($$.m_node, @1, @7); } + setStatementLocation($$.m_node, @1, @7); } | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column); - SET_EXCEPTION_LOCATION(forIn, @4.first_column, @6.first_column + 1, @7.last_column); + setExceptionLocation(forIn, @4.first_column, @6.first_column + 1, @7.last_column); appendToVarDeclarationList(GLOBAL_DATA, $9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $5.m_features | $7.m_features | $9.m_features, $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @8); } + setStatementLocation($$.m_node, @1, @8); } ; ExprOpt: @@ -1020,63 +1029,63 @@ ExprNoInOpt: ContinueStatement: CONTINUE ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | CONTINUE error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | CONTINUE IDENT ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | CONTINUE IDENT error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; BreakStatement: BREAK ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } | BREAK error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | BREAK IDENT ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @3); } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @3); } | BREAK IDENT error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ReturnStatement: RETURN ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } | RETURN error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | RETURN Expr ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @3); } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @3); } | RETURN Expr error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; WithStatement: WITH '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features | WithFeature, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; SwitchStatement: SWITCH '(' Expr ')' CaseBlock { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; CaseBlock: @@ -1090,7 +1099,7 @@ CaseBlock: ; CaseClausesOpt: -/* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; $$.m_features = 0; $$.m_numConstants = 0; } + /* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; $$.m_features = 0; $$.m_numConstants = 0; } | CaseClauses ; @@ -1122,18 +1131,18 @@ DefaultClause: LabelledStatement: IDENT ':' Statement { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *$1, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); } ; ThrowStatement: THROW Expr ';' { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); } | THROW Expr error { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; @@ -1143,57 +1152,57 @@ TryStatement: mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations), $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0), mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $2.m_features | $7.m_features | CatchFeature, $2.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | TRY Block CATCH '(' IDENT ')' Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node), mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations), mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations), $2.m_features | $7.m_features | $9.m_features | CatchFeature, $2.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } ; DebuggerStatement: DEBUGGER ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | DEBUGGER error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } ; FunctionDeclaration: - FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); } + FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); setStatementLocation($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); } | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); + { + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - DBG($7, @6, @8); - $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); + $7->setUsesArguments(); + setStatementLocation($7, @6, @8); + $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); } ; FunctionExpr: - FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, LEXER->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); DBG($5, @4, @6); } - | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, LEXER->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0); - if ($3.m_features & ArgumentsFeature) + FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); } + | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE + { + $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0); + if ($3.m_features & ArgumentsFeature) $6->setUsesArguments(); - DBG($6, @5, @7); + setStatementLocation($6, @5, @7); } - | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); } - | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), $4.m_features | ClosureFeature, 0); + | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); } + | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE + { + $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - DBG($7, @6, @8); + setStatementLocation($7, @6, @8); } ; @@ -1241,8 +1250,8 @@ Literal_NoNode: | FALSETOKEN | NUMBER { } | STRING { } - | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } - | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } + | '/' /* regexp */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } + | DIVEQUAL /* regexp with /= */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } ; Property_NoNode: @@ -1824,26 +1833,28 @@ SourceElements_NoNode: %% -static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) +#undef GLOBAL_DATA + +static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) { if (!loc->isLocation()) - return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot); + return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(loc); if (op == OpEqual) { - AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); - SET_EXCEPTION_LOCATION(node, start, divot, end); + AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments); + setExceptionLocation(node, start, divot, end); return node; } else - return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); + return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); else { - ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } @@ -1851,117 +1862,117 @@ static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Oper ASSERT(loc->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); + return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); - ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PrefixDotNode* node = new (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->startOffset()); return node; } -static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PostfixDotNode* node = new (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) { CodeFeatures features = func.m_features | args.m_features; int numConstants = func.m_numConstants + args.m_numConstants; if (!func.m_node->isLocation()) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); if (func.m_node->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node); const Identifier& identifier = resolve->identifier(); - if (identifier == GLOBAL_DATA->propertyNames->eval) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); + if (identifier == globalData->propertyNames->eval) + return createNodeInfo<ExpressionNode*>(new (globalData) EvalFunctionCallNode(globalData, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallResolveNode(globalData, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); } if (func.m_node->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node); - FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); + FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } ASSERT(func.m_node->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node); FunctionCallDotNode* node; - if (dot->identifier() == GLOBAL_DATA->propertyNames->call) - node = new (GLOBAL_DATA) CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - else if (dot->identifier() == GLOBAL_DATA->propertyNames->apply) - node = new (GLOBAL_DATA) ApplyFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + if (dot->identifier() == globalData->propertyNames->call) + node = new (globalData) CallFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + else if (dot->identifier() == globalData->propertyNames->apply) + node = new (globalData) ApplyFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); else - node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } -static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeTypeOfNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier()); + return new (globalData) TypeOfResolveNode(globalData, resolve->identifier()); } - return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr); + return new (globalData) TypeOfValueNode(globalData, expr); } -static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end) +static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr); + return new (globalData) DeleteValueNode(globalData, expr); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); + return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); } -static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) { PropertyNode::Type type; if (getOrSet == "get") @@ -1970,10 +1981,10 @@ static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Ident type = PropertyNode::Setter; else return 0; - return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type); + return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type); } -static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) +static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n) { if (n->isNumber()) { NumberNode* number = static_cast<NumberNode*>(n); @@ -1984,92 +1995,92 @@ static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) } } - return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n); + return new (globalData) NegateNode(globalData, n); } -static NumberNode* makeNumberNode(void* globalPtr, double d) +static NumberNode* makeNumberNode(JSGlobalData* globalData, double d) { - return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d); + return new (globalData) NumberNode(globalData, d); } -static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isNumber()) - return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value())); - return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr); + return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value())); + return new (globalData) BitwiseNotNode(globalData, expr); } -static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2); + return new (globalData) UnaryPlusNode(globalData, expr2); if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1); + return new (globalData) UnaryPlusNode(globalData, expr1); - return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); + return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); + return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); + return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments); } -/* called by yyparse on error */ -int yyerror(const char *) +// Called by yyparse on error. +int yyerror(const char*) { return 1; } -/* may we automatically insert a semicolon ? */ +// May we automatically insert a semicolon? static bool allowAutomaticSemicolon(Lexer& lexer, int yychar) { return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator(); } -static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init) +static ExpressionNode* combineCommaNodes(JSGlobalData* globalData, ExpressionNode* list, ExpressionNode* init) { if (!list) return init; @@ -2077,17 +2088,15 @@ static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, static_cast<CommaNode*>(list)->append(init); return list; } - return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init); + return new (globalData) CommaNode(globalData, list, init); } // We turn variable declarations into either assignments or empty // statements (which later get stripped out), because the actual // declaration work is hoisted up to the start of the function body -static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr) +static StatementNode* makeVarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) { if (!expr) - return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA); - return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr); + return new (globalData) EmptyStatementNode(globalData); + return new (globalData) VarStatementNode(globalData, expr); } - -#undef GLOBAL_DATA diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp index c36763c..ec700bd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp @@ -142,8 +142,10 @@ ALWAYS_INLINE void Lexer::shift4() m_code += 4; } -void Lexer::setCode(const SourceCode& source) +void Lexer::setCode(const SourceCode& source, ParserArena& arena) { + m_arena = &arena.identifierArena(); + m_lineNumber = source.firstLine(); m_delimited = false; m_lastToken = -1; @@ -206,10 +208,9 @@ void Lexer::shiftLineTerminator() ++m_lineNumber; } -ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length) +ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length) { - m_identifiers.append(Identifier(m_globalData, characters, length)); - return &m_identifiers.last(); + return &m_arena->makeIdentifier(m_globalData, characters, length); } inline bool Lexer::lastTokenWasRestrKeyword() const @@ -914,48 +915,110 @@ returnError: return -1; } -bool Lexer::scanRegExp() +bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix) { ASSERT(m_buffer16.isEmpty()); bool lastWasEscape = false; bool inBrackets = false; + if (patternPrefix) { + ASSERT(!isLineTerminator(patternPrefix)); + ASSERT(patternPrefix != '/'); + ASSERT(patternPrefix != '['); + record16(patternPrefix); + } + while (true) { - if (isLineTerminator(m_current) || m_current == -1) - return false; - if (m_current != '/' || lastWasEscape || inBrackets) { - // keep track of '[' and ']' - if (!lastWasEscape) { - if (m_current == '[' && !inBrackets) - inBrackets = true; - if (m_current == ']' && inBrackets) - inBrackets = false; - } - record16(m_current); - lastWasEscape = !lastWasEscape && m_current == '\\'; - } else { // end of regexp - m_pattern = UString(m_buffer16); + int current = m_current; + + if (isLineTerminator(current) || current == -1) { m_buffer16.resize(0); - shift1(); - break; + return false; } + shift1(); + + if (current == '/' && !lastWasEscape && !inBrackets) + break; + + record16(current); + + if (lastWasEscape) { + lastWasEscape = false; + continue; + } + + switch (current) { + case '[': + inBrackets = true; + break; + case ']': + inBrackets = false; + break; + case '\\': + lastWasEscape = true; + break; + } } + pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size()); + m_buffer16.resize(0); + while (isIdentPart(m_current)) { record16(m_current); shift1(); } - m_flags = UString(m_buffer16); + + flags = makeIdentifier(m_buffer16.data(), m_buffer16.size()); m_buffer16.resize(0); return true; } +bool Lexer::skipRegExp() +{ + bool lastWasEscape = false; + bool inBrackets = false; + + while (true) { + int current = m_current; + + if (isLineTerminator(current) || current == -1) + return false; + + shift1(); + + if (current == '/' && !lastWasEscape && !inBrackets) + break; + + if (lastWasEscape) { + lastWasEscape = false; + continue; + } + + switch (current) { + case '[': + inBrackets = true; + break; + case ']': + inBrackets = false; + break; + case '\\': + lastWasEscape = true; + break; + } + } + + while (isIdentPart(m_current)) + shift1(); + + return true; +} + void Lexer::clear() { - m_identifiers.clear(); + m_arena = 0; m_codeWithoutBOMs.clear(); Vector<char> newBuffer8; @@ -967,9 +1030,6 @@ void Lexer::clear() m_buffer16.swap(newBuffer16); m_isReparsing = false; - - m_pattern = UString(); - m_flags = UString(); } SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h index 0ef6dd4..885e4d9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h @@ -23,6 +23,7 @@ #define Lexer_h #include "Lookup.h" +#include "ParserArena.h" #include "SourceCode.h" #include <wtf/ASCIICType.h> #include <wtf/SegmentedVector.h> @@ -42,7 +43,7 @@ namespace JSC { static UChar convertUnicode(int c1, int c2, int c3, int c4); // Functions to set up parsing. - void setCode(const SourceCode&); + void setCode(const SourceCode&, ParserArena&); void setIsReparsing() { m_isReparsing = true; } // Functions for the parser itself. @@ -50,9 +51,8 @@ namespace JSC { int lineNumber() const { return m_lineNumber; } bool prevTerminator() const { return m_terminator; } SourceCode sourceCode(int openBrace, int closeBrace, int firstLine); - bool scanRegExp(); - const UString& pattern() const { return m_pattern; } - const UString& flags() const { return m_flags; } + bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0); + bool skipRegExp(); // Functions for use after parsing. bool sawError() const { return m_error; } @@ -79,12 +79,11 @@ namespace JSC { int currentOffset() const; const UChar* currentCharacter() const; - JSC::Identifier* makeIdentifier(const UChar* buffer, size_t length); + const Identifier* makeIdentifier(const UChar* characters, size_t length); bool lastTokenWasRestrKeyword() const; static const size_t initialReadBufferCapacity = 32; - static const size_t initialIdentifierTableCapacity = 64; int m_lineNumber; // this variable is supposed to keep index of last new line character ('\n' or '\r\n'or '\n\r'...) @@ -112,13 +111,10 @@ namespace JSC { int m_next2; int m_next3; - WTF::SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers; + IdentifierArena* m_arena; JSGlobalData* m_globalData; - UString m_pattern; - UString m_flags; - const HashTable m_keywordTable; Vector<UChar> m_codeWithoutBOMs; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h index a4374d3..5431e18 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h @@ -61,19 +61,19 @@ namespace JSC { { } - inline NumberNode::NumberNode(JSGlobalData* globalData, double v) + inline NumberNode::NumberNode(JSGlobalData* globalData, double value) : ExpressionNode(globalData, ResultType::numberType()) - , m_double(v) + , m_value(value) { } - inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& v) + inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& value) : ExpressionNode(globalData, ResultType::stringType()) - , m_value(v) + , m_value(value) { } - inline RegExpNode::RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) + inline RegExpNode::RegExpNode(JSGlobalData* globalData, const Identifier& pattern, const Identifier& flags) : ExpressionNode(globalData) , m_pattern(pattern) , m_flags(flags) @@ -138,6 +138,13 @@ namespace JSC { { } + inline PropertyNode::PropertyNode(JSGlobalData* globalData, double name, ExpressionNode* assign, Type type) + : m_name(globalData->parser->arena().identifierArena().makeNumericIdentifier(globalData, name)) + , m_assign(assign) + , m_type(type) + { + } + inline PropertyListNode::PropertyListNode(JSGlobalData* globalData, PropertyNode* node) : Node(globalData) , m_node(node) @@ -725,6 +732,7 @@ namespace JSC { inline ContinueNode::ContinueNode(JSGlobalData* globalData) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) { } @@ -736,6 +744,7 @@ namespace JSC { inline BreakNode::BreakNode(JSGlobalData* globalData) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) { } @@ -798,32 +807,22 @@ namespace JSC { inline FuncExprNode::FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter) : ExpressionNode(globalData) - , ParserArenaRefCounted(globalData) - , m_ident(ident) , m_body(body) { - m_body->finishParsing(source, parameter); + m_body->finishParsing(source, parameter, ident); } inline FuncDeclNode::FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter) : StatementNode(globalData) - , ParserArenaRefCounted(globalData) - , m_ident(ident) , m_body(body) { - m_body->finishParsing(source, parameter); - } - - inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr) - : m_expr(expr) - { + m_body->finishParsing(source, parameter, ident); } - inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* children) + inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* statements) : m_expr(expr) + , m_statements(statements) { - if (children) - children->releaseContentsIntoVector(m_children); } inline ClauseListNode::ClauseListNode(JSGlobalData*, CaseClauseNode* clause) @@ -861,15 +860,15 @@ namespace JSC { { } - inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children) + inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* statements) : StatementNode(globalData) + , m_statements(statements) { - if (children) - children->releaseContentsIntoVector(m_children); } inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) , m_init(0) , m_lexpr(l) , m_expr(expr) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp index 9d9fe72..7170f73 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp @@ -49,7 +49,28 @@ using namespace WTF; namespace JSC { -static void substitute(UString& string, const UString& substring); +/* + Details of the emitBytecode function. + + Return value: The register holding the production's value. + dst: An optional parameter specifying the most efficient destination at + which to store the production's value. The callee must honor dst. + + The dst argument provides for a crude form of copy propagation. For example, + + x = 1 + + becomes + + load r[x], 1 + + instead of + + load r0, 1 + mov r[x], r0 + + because the assignment node, "x =", passes r[x] as dst to the number node, "1". +*/ // ------------------------------ ThrowableExpressionData -------------------------------- @@ -63,24 +84,29 @@ static void substitute(UString& string, const UString& substring) string = newString; } -RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg) +RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message) { generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg)); + RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); generator.emitThrow(exception); return exception; } -RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label) +RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label) { - UString message = msg; - substitute(message, label.ustring()); + UString message = messageTemplate; + substitute(message, label); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message)); + RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); generator.emitThrow(exception); return exception; } +inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label) +{ + return emitThrowError(generator, type, messageTemplate, label.ustring()); +} + // ------------------------------ StatementNode -------------------------------- void StatementNode::setLoc(int firstLine, int lastLine, int column) @@ -99,6 +125,18 @@ void SourceElements::append(StatementNode* statement) m_statements.append(statement); } +inline StatementNode* SourceElements::singleStatement() const +{ + size_t size = m_statements.size(); + return size == 1 ? m_statements[0] : 0; +} + +inline StatementNode* SourceElements::lastStatement() const +{ + size_t size = m_statements.size(); + return size ? m_statements[size - 1] : 0; +} + // ------------------------------ NullNode ------------------------------------- RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -123,7 +161,7 @@ RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d { if (dst == generator.ignoredResult()) return 0; - return generator.emitLoad(dst, m_double); + return generator.emitLoad(dst, m_value); } // ------------------------------ StringNode ----------------------------------- @@ -139,9 +177,9 @@ RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags); + RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring()); if (!regExp->isValid()) - return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str()); + return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage()); if (dst == generator.ignoredResult()) return 0; return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get()); @@ -356,7 +394,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RefPtr<RegisterID> thisRegister = generator.newTemporary(); int identifierStart = divot() - startOffset(); generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0); - generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident); + generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident); return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); } @@ -376,11 +414,12 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr<RegisterID> base = generator.emitNode(m_base); + RefPtr<RegisterID> function = generator.tempDestination(dst); + RefPtr<RegisterID> thisRegister = generator.newTemporary(); + generator.emitNode(thisRegister.get(), m_base); generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); generator.emitMethodCheck(); - RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); - RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); + generator.emitGetById(function.get(), thisRegister.get(), m_ident); return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); } @@ -596,7 +635,9 @@ RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterI RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { - return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference."); + return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus + ? "Postfix ++ operator applied to value that is not a reference." + : "Postfix -- operator applied to value that is not a reference."); } // ------------------------------ DeleteResolveNode ----------------------------------- @@ -758,7 +799,9 @@ RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { - return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference."); + return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus + ? "Prefix ++ operator applied to value that is not a reference." + : "Prefix -- operator applied to value that is not a reference."); } // ------------------------------ Unary Operation Nodes ----------------------------------- @@ -1205,7 +1248,13 @@ RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator) return generator.emitNode(local, m_init); } - + + if (generator.codeType() != EvalCode) { + if (m_init) + return generator.emitNode(m_init); + else + return generator.emitResolve(generator.newTemporary(), m_ident); + } // FIXME: While this code should only be hit in eval code, it will potentially // assign to the wrong base if m_ident exists in an intervening dynamic scope. RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident); @@ -1230,20 +1279,26 @@ RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, Regis return generator.emitNode(m_next); } -// ------------------------------ Helper functions for handling Vectors of StatementNode ------------------------------- +// ------------------------------ SourceElements ------------------------------- -static inline void statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst) +inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - size_t size = statements.size(); + size_t size = m_statements.size(); for (size_t i = 0; i < size; ++i) - generator.emitNode(dst, statements[i]); + generator.emitNode(dst, m_statements[i]); } // ------------------------------ BlockNode ------------------------------------ +inline StatementNode* BlockNode::lastStatement() const +{ + return m_statements ? m_statements->lastStatement() : 0; +} + RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - statementListEmitCode(m_children, generator, dst); + if (m_statements) + m_statements->emitBytecode(generator, dst); return 0; } @@ -1380,9 +1435,6 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (dst == generator.ignoredResult()) - dst = 0; - RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column()); @@ -1558,6 +1610,14 @@ RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst return result; } +// ------------------------------ CaseClauseNode -------------------------------- + +inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) +{ + if (m_statements) + m_statements->emitBytecode(generator, dst); +} + // ------------------------------ CaseBlockNode -------------------------------- enum SwitchKind { @@ -1574,13 +1634,11 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector.append(clauseExpression); if (clauseExpression->isNumber()) { double value = static_cast<NumberNode*>(clauseExpression)->value(); - JSValue jsValue = JSValue::makeInt32Fast(static_cast<int32_t>(value)); - if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) { + int32_t intVal = static_cast<int32_t>(value); + if ((typeForTable & ~SwitchNumber) || (intVal != value)) { typeForTable = SwitchNeither; break; } - int32_t intVal = static_cast<int32_t>(value); - ASSERT(intVal == value); if (intVal < min_num) min_num = intVal; if (intVal > max_num) @@ -1679,17 +1737,17 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re size_t i = 0; for (ClauseListNode* list = m_list1; list; list = list->getNext()) { generator.emitLabel(labelVector[i++].get()); - statementListEmitCode(list->getClause()->children(), generator, dst); + list->getClause()->emitBytecode(generator, dst); } if (m_defaultClause) { generator.emitLabel(defaultLabel.get()); - statementListEmitCode(m_defaultClause->children(), generator, dst); + m_defaultClause->emitBytecode(generator, dst); } for (ClauseListNode* list = m_list2; list; list = list->getNext()) { generator.emitLabel(labelVector[i++].get()); - statementListEmitCode(list->getClause()->children(), generator, dst); + list->getClause()->emitBytecode(generator, dst); } if (!m_defaultClause) generator.emitLabel(defaultLabel.get()); @@ -1751,12 +1809,14 @@ RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { + // NOTE: The catch and finally blocks must be labeled explicitly, so the + // optimizer knows they may be jumped to from anywhere. + #ifndef QT_BUILD_SCRIPT_LIB generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column()); #endif RefPtr<Label> tryStartLabel = generator.newLabel(); - RefPtr<Label> tryEndLabel = generator.newLabel(); RefPtr<Label> finallyStart; RefPtr<RegisterID> finallyReturnAddr; if (m_finallyBlock) { @@ -1764,14 +1824,19 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) finallyReturnAddr = generator.newTemporary(); generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get()); } + generator.emitLabel(tryStartLabel.get()); generator.emitNode(dst, m_tryBlock); - generator.emitLabel(tryEndLabel.get()); if (m_catchBlock) { - RefPtr<Label> handlerEndLabel = generator.newLabel(); - generator.emitJump(handlerEndLabel.get()); - RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get()); + RefPtr<Label> catchEndLabel = generator.newLabel(); + + // Normal path: jump over the catch block. + generator.emitJump(catchEndLabel.get()); + + // Uncaught exception path: the catch block. + RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); + RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); if (m_catchHasEval) { RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary()); generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get()); @@ -1781,7 +1846,7 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get()); generator.emitNode(dst, m_catchBlock); generator.emitPopScope(); - generator.emitLabel(handlerEndLabel.get()); + generator.emitLabel(catchEndLabel.get()); } if (m_finallyBlock) { @@ -1792,21 +1857,18 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) // approach to not clobbering anything important RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister(); RefPtr<Label> finallyEndLabel = generator.newLabel(); + + // Normal path: invoke the finally block, then jump over it. generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); - // Use a label to record the subtle fact that sret will return to the - // next instruction. sret is the only way to jump without an explicit label. - generator.emitLabel(generator.newLabel().get()); generator.emitJump(finallyEndLabel.get()); - // Finally block for exception path - RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get()); + // Uncaught exception path: invoke the finally block, then re-throw the exception. + RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); + RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); - // Use a label to record the subtle fact that sret will return to the - // next instruction. sret is the only way to jump without an explicit label. - generator.emitLabel(generator.newLabel().get()); generator.emitThrow(tempExceptionRegister.get()); - // emit the finally block itself + // The finally block. generator.emitLabel(finallyStart.get()); generator.emitNode(dst, m_finallyBlock); generator.emitSubroutineReturn(finallyReturnAddr.get()); @@ -1819,27 +1881,15 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) // -----------------------------ScopeNodeData --------------------------- -ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants) +ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants) : m_numConstants(numConstants) + , m_statements(statements) { m_arena.swap(arena); if (varStack) m_varStack.swap(*varStack); if (funcStack) m_functionStack.swap(*funcStack); - if (children) - children->releaseContentsIntoVector(m_children); -} - -void ScopeNodeData::mark() -{ - FunctionStack::iterator end = m_functionStack.end(); - for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) { - FunctionBodyNode* body = (*ptr)->body(); - if (!body->isGenerated()) - continue; - body->generatedBytecode().mark(); - } } // ------------------------------ ScopeNode ----------------------------- @@ -1868,6 +1918,17 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceE #endif } +inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst) +{ + if (m_data->m_statements) + m_data->m_statements->emitBytecode(generator, dst); +} + +StatementNode* ScopeNode::singleStatement() const +{ + return m_data->m_statements ? m_data->m_statements->singleStatement() : 0; +} + // ------------------------------ ProgramNode ----------------------------- inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants) @@ -1892,37 +1953,13 @@ RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) RefPtr<RegisterID> dstRegister = generator.newTemporary(); generator.emitLoad(dstRegister.get(), jsUndefined()); - statementListEmitCode(children(), generator, dstRegister.get()); + emitStatementsBytecode(generator, dstRegister.get()); generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column()); generator.emitEnd(dstRegister.get()); return 0; } -void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get())); - generator->generate(); - - destroyData(); -} - -#if ENABLE(JIT) -void ProgramNode::generateJITCode(ScopeChainNode* scopeChainNode) -{ - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); -} -#endif - // ------------------------------ EvalNode ----------------------------- inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants) @@ -1947,131 +1984,46 @@ RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) RefPtr<RegisterID> dstRegister = generator.newTemporary(); generator.emitLoad(dstRegister.get(), jsUndefined()); - statementListEmitCode(children(), generator, dstRegister.get()); + emitStatementsBytecode(generator, dstRegister.get()); generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column()); generator.emitEnd(dstRegister.get()); return 0; } -void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->generate(); - - // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time, - // so the entire ScopeNodeData cannot be destoyed. - children().clear(); -} - -EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom) -{ - ASSERT(!m_code); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom); - generator->generate(); - - return *m_code; -} - -void EvalNode::mark() -{ - // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that - data()->mark(); -} +// ------------------------------ FunctionBodyNode ----------------------------- -#if ENABLE(JIT) -void EvalNode::generateJITCode(ScopeChainNode* scopeChainNode) +FunctionParameters::FunctionParameters(ParameterNode* firstParameter) { - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); + for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) + append(parameter->ident()); } -#endif - -// ------------------------------ FunctionBodyNode ----------------------------- inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData) : ScopeNode(globalData) - , m_parameters(0) - , m_parameterCount(0) { -#ifdef QT_BUILD_SCRIPT_LIB - sourceToken = globalData->scriptpool->objectRegister(); -#endif } inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants) : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants) - , m_parameters(0) - , m_parameterCount(0) { -#ifdef QT_BUILD_SCRIPT_LIB - sourceToken = globalData->scriptpool->objectRegister(); -#endif } FunctionBodyNode::~FunctionBodyNode() { -#ifdef QT_BUILD_SCRIPT_LIB - if (sourceToken) delete sourceToken; -#endif - for (size_t i = 0; i < m_parameterCount; ++i) - m_parameters[i].~Identifier(); - fastFree(m_parameters); } -void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter) +void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) { - Vector<Identifier> parameters; - for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) - parameters.append(parameter->ident()); - size_t count = parameters.size(); - setSource(source); - finishParsing(parameters.releaseBuffer(), count); + finishParsing(FunctionParameters::create(firstParameter), ident); } -void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount) +void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident) { ASSERT(!source().isNull()); m_parameters = parameters; - m_parameterCount = parameterCount; -} - -void FunctionBodyNode::mark() -{ - if (m_code) - m_code->mark(); -} - -#if ENABLE(JIT) -PassRefPtr<FunctionBodyNode> FunctionBodyNode::createNativeThunk(JSGlobalData* globalData) -{ - RefPtr<FunctionBodyNode> body = new FunctionBodyNode(globalData); - globalData->parser->arena().reset(); - body->m_code.set(new CodeBlock(body.get())); - body->m_jitCode = JITCode(JITCode::HostFunction(globalData->jitStubs.ctiNativeCallThunk())); - return body.release(); -} -#endif - -bool FunctionBodyNode::isHostFunction() const -{ - return m_code && m_code->codeType() == NativeCode; + m_ident = ident; } FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData) @@ -2090,59 +2042,14 @@ PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, return node.release(); } -void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - // This branch is only necessary since you can still create a non-stub FunctionBodyNode by - // calling Parser::parse<FunctionBodyNode>(). - if (!data()) - scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this); - ASSERT(data()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->generate(); - - destroyData(); -} - -#if ENABLE(JIT) -void FunctionBodyNode::generateJITCode(ScopeChainNode* scopeChainNode) -{ - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); -} -#endif - -CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom) -{ - ASSERT(!m_code); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom); - generator->generate(); - - return *m_code; -} - RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine(), column()); - statementListEmitCode(children(), generator, generator.ignoredResult()); - if (children().size() && children().last()->isBlock()) { - BlockNode* blockNode = static_cast<BlockNode*>(children().last()); - if (blockNode->children().size() && blockNode->children().last()->isReturnNode()) + emitStatementsBytecode(generator, generator.ignoredResult()); + StatementNode* singleStatement = this->singleStatement(); + if (singleStatement && singleStatement->isBlock()) { + StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); + if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) return 0; } @@ -2152,32 +2059,8 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe return 0; } -UString FunctionBodyNode::paramString() const -{ - UString s(""); - for (size_t pos = 0; pos < m_parameterCount; ++pos) { - if (!s.isEmpty()) - s += ", "; - s += parameters()[pos].ustring(); - } - - return s; -} - -Identifier* FunctionBodyNode::copyParameters() -{ - Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier))); - VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters); - return parameters; -} - // ------------------------------ FuncDeclNode --------------------------------- -JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain) -{ - return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain); -} - RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { if (dst == generator.ignoredResult()) @@ -2192,24 +2075,4 @@ RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* return generator.emitNewFunctionExpression(generator.finalDestination(dst), this); } -JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain) -{ - JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain); - - /* - The Identifier in a FunctionExpression can be referenced from inside - the FunctionExpression's FunctionBody to allow the function to call - itself recursively. However, unlike in a FunctionDeclaration, the - Identifier in a FunctionExpression cannot be referenced from and - does not affect the scope enclosing the FunctionExpression. - */ - - if (!m_ident.isNull()) { - JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete); - func->scope().push(functionScopeObject); - } - - return func; -} - } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h index 185cede..2f8d850 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h @@ -34,25 +34,17 @@ #include "SourceCode.h" #include "SymbolTable.h" #include <wtf/MathExtras.h> -#include <wtf/OwnPtr.h> - -#ifdef QT_BUILD_SCRIPT_LIB -#include "SourcePoolQt.h" -#endif namespace JSC { class ArgumentListNode; - class CodeBlock; class BytecodeGenerator; - class FuncDeclNode; - class EvalCodeBlock; - class JSFunction; - class ProgramCodeBlock; + class FunctionBodyNode; class PropertyListNode; class ReadModifyResolveNode; class RegisterID; class ScopeChainNode; + class ScopeNode; typedef unsigned CodeFeatures; @@ -90,8 +82,8 @@ namespace JSC { namespace DeclarationStacks { enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; - typedef Vector<std::pair<Identifier, unsigned> > VarStack; - typedef Vector<FuncDeclNode*> FunctionStack; + typedef Vector<std::pair<const Identifier*, unsigned> > VarStack; + typedef Vector<FunctionBodyNode*> FunctionStack; } struct SwitchInfo { @@ -100,24 +92,23 @@ namespace JSC { SwitchType switchType; }; - class ParserArenaDeletable { - protected: - ParserArenaDeletable() { } + class ParserArenaFreeable { + public: + // ParserArenaFreeable objects are are freed when the arena is deleted. + // Destructors are not called. Clients must not call delete on such objects. + void* operator new(size_t, JSGlobalData*); + }; + class ParserArenaDeletable { public: virtual ~ParserArenaDeletable() { } - // Objects created with this version of new are deleted when the arena is deleted. + // ParserArenaDeletable objects are deleted when the arena is deleted. + // Clients must not call delete directly on such objects. void* operator new(size_t, JSGlobalData*); - - // Objects created with this version of new are not deleted when the arena is deleted. - // Other arrangements must be made. - void* operator new(size_t); - - void operator delete(void*); }; - class ParserArenaRefCounted : public RefCountedCustomAllocated<ParserArenaRefCounted> { + class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> { protected: ParserArenaRefCounted(JSGlobalData*); @@ -128,34 +119,14 @@ namespace JSC { } }; - class Node : public ParserArenaDeletable { + class Node : public ParserArenaFreeable { protected: Node(JSGlobalData*); public: - /* - Return value: The register holding the production's value. - dst: An optional parameter specifying the most efficient - destination at which to store the production's value. - The callee must honor dst. - - dst provides for a crude form of copy propagation. For example, + virtual ~Node() { } - x = 1 - - becomes - - load r[x], 1 - - instead of - - load r0, 1 - mov r[x], r0 - - because the assignment node, "x =", passes r[x] as dst to the number - node, "1". - */ - virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) = 0; + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; int lineNo() const { return m_line; } @@ -164,9 +135,10 @@ namespace JSC { }; class ExpressionNode : public Node { - public: + protected: ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType()); + public: virtual bool isNumber() const { return false; } virtual bool isString() const { return false; } virtual bool isNull() const { return false; } @@ -184,18 +156,16 @@ namespace JSC { ResultType resultDescriptor() const { return m_resultType; } - // This needs to be in public in order to compile using GCC 3.x - typedef enum { EvalOperator, FunctionCall } CallerType; - private: ResultType m_resultType; }; class StatementNode : public Node { - public: + protected: StatementNode(JSGlobalData*); - void setLoc(int line0, int line1, int column); + public: + void setLoc(int firstLine, int lastLine, int column); int firstLine() const { return lineNo(); } int lastLine() const { return m_lastLine; } int column() const { return m_column; } @@ -235,10 +205,10 @@ namespace JSC { class NumberNode : public ExpressionNode { public: - NumberNode(JSGlobalData*, double v); + NumberNode(JSGlobalData*, double value); - double value() const { return m_double; } - void setValue(double d) { m_double = d; } + double value() const { return m_value; } + void setValue(double value) { m_value = value; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -246,22 +216,23 @@ namespace JSC { virtual bool isNumber() const { return true; } virtual bool isPure(BytecodeGenerator&) const { return true; } - double m_double; + double m_value; }; class StringNode : public ExpressionNode { public: - StringNode(JSGlobalData*, const Identifier& v); + StringNode(JSGlobalData*, const Identifier&); const Identifier& value() { return m_value; } - virtual bool isPure(BytecodeGenerator&) const { return true; } private: + virtual bool isPure(BytecodeGenerator&) const { return true; } + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isString() const { return true; } - Identifier m_value; + const Identifier& m_value; }; class ThrowableExpressionData { @@ -292,8 +263,9 @@ namespace JSC { uint16_t endOffset() const { return m_endOffset; } protected: - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg); - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const UString&); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const Identifier&); private: uint32_t m_divot; @@ -304,8 +276,7 @@ namespace JSC { class ThrowableSubExpressionData : public ThrowableExpressionData { public: ThrowableSubExpressionData() - : ThrowableExpressionData() - , m_subexpressionDivotOffset(0) + : m_subexpressionDivotOffset(0) , m_subexpressionEndOffset(0) { } @@ -334,8 +305,7 @@ namespace JSC { class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { public: ThrowablePrefixedSubExpressionData() - : ThrowableExpressionData() - , m_subexpressionDivotOffset(0) + : m_subexpressionDivotOffset(0) , m_subexpressionStartOffset(0) { } @@ -363,13 +333,13 @@ namespace JSC { class RegExpNode : public ExpressionNode, public ThrowableExpressionData { public: - RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags); + RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - UString m_pattern; - UString m_flags; + const Identifier& m_pattern; + const Identifier& m_flags; }; class ThisNode : public ExpressionNode { @@ -393,11 +363,11 @@ namespace JSC { virtual bool isLocation() const { return true; } virtual bool isResolveNode() const { return true; } - Identifier m_ident; + const Identifier& m_ident; int32_t m_startOffset; }; - class ElementNode : public ParserArenaDeletable { + class ElementNode : public ParserArenaFreeable { public: ElementNode(JSGlobalData*, int elision, ExpressionNode*); ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*); @@ -430,17 +400,18 @@ namespace JSC { bool m_optional; }; - class PropertyNode : public ParserArenaDeletable { + class PropertyNode : public ParserArenaFreeable { public: enum Type { Constant, Getter, Setter }; PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type); + PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type); const Identifier& name() const { return m_name; } private: friend class PropertyListNode; - Identifier m_name; + const Identifier& m_name; ExpressionNode* m_assign; Type m_type; }; @@ -500,7 +471,7 @@ namespace JSC { virtual bool isDotAccessorNode() const { return true; } ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; }; class ArgumentListNode : public Node { @@ -515,7 +486,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); }; - class ArgumentsNode : public ParserArenaDeletable { + class ArgumentsNode : public ParserArenaFreeable { public: ArgumentsNode(JSGlobalData*); ArgumentsNode(JSGlobalData*, ArgumentListNode*); @@ -563,7 +534,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ArgumentsNode* m_args; size_t m_index; // Used by LocalVarFunctionCallNode. size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode @@ -590,7 +561,7 @@ namespace JSC { protected: ExpressionNode* m_base; - const Identifier m_ident; + const Identifier& m_ident; ArgumentsNode* m_args; }; @@ -615,7 +586,7 @@ namespace JSC { PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset); protected: - const Identifier m_ident; + const Identifier& m_ident; }; class PostfixResolveNode : public PrePostResolveNode { @@ -648,7 +619,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; Operator m_operator; }; @@ -670,7 +641,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { @@ -692,7 +663,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; }; class DeleteValueNode : public ExpressionNode { @@ -724,7 +695,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class TypeOfValueNode : public ExpressionNode { @@ -767,7 +738,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; Operator m_operator; }; @@ -826,7 +797,7 @@ namespace JSC { BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); - RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); + RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1009,7 +980,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; size_t m_index; // Used by ReadModifyLocalVarNode. Operator m_operator; @@ -1023,7 +994,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; size_t m_index; // Used by ReadModifyLocalVarNode. bool m_rightHasAssignments; @@ -1066,7 +1037,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; bool m_rightHasAssignments; }; @@ -1079,7 +1050,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; Operator m_operator : 31; bool m_rightHasAssignments : 1; @@ -1099,10 +1070,12 @@ namespace JSC { typedef Vector<ExpressionNode*, 8> ExpressionVector; - class CommaNode : public ExpressionNode { + class CommaNode : public ExpressionNode, public ParserArenaDeletable { public: CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2); + using ParserArenaDeletable::operator new; + void append(ExpressionNode* expr) { m_expressions.append(expr); } private: @@ -1123,7 +1096,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual RegisterID* emitCodeSingle(BytecodeGenerator&); - Identifier m_ident; + const Identifier& m_ident; public: ConstDeclNode* m_next; @@ -1142,36 +1115,33 @@ namespace JSC { ConstDeclNode* m_next; }; - typedef Vector<StatementNode*> StatementVector; - class SourceElements : public ParserArenaDeletable { public: SourceElements(JSGlobalData*); void append(StatementNode*); - void releaseContentsIntoVector(StatementVector& destination) - { - ASSERT(destination.isEmpty()); - m_statements.swap(destination); - destination.shrinkToFit(); - } + + StatementNode* singleStatement() const; + StatementNode* lastStatement() const; + + void emitBytecode(BytecodeGenerator&, RegisterID* destination); private: - StatementVector m_statements; + Vector<StatementNode*> m_statements; }; class BlockNode : public StatementNode { public: - BlockNode(JSGlobalData*, SourceElements* children); + BlockNode(JSGlobalData*, SourceElements* = 0); - StatementVector& children() { return m_children; } + StatementNode* lastStatement() const; private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isBlock() const { return true; } - StatementVector m_children; + SourceElements* m_statements; }; class EmptyStatementNode : public StatementNode { @@ -1281,7 +1251,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_init; ExpressionNode* m_lexpr; ExpressionNode* m_expr; @@ -1297,7 +1267,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class BreakNode : public StatementNode, public ThrowableExpressionData { @@ -1308,7 +1278,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class ReturnNode : public StatementNode, public ThrowableExpressionData { @@ -1343,7 +1313,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_name; + const Identifier& m_name; StatementNode* m_statement; }; @@ -1362,16 +1332,16 @@ namespace JSC { TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock); private: - virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0); + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); StatementNode* m_tryBlock; - Identifier m_exceptionIdent; + const Identifier& m_exceptionIdent; StatementNode* m_catchBlock; StatementNode* m_finallyBlock; bool m_catchHasEval; }; - class ParameterNode : public ParserArenaDeletable { + class ParameterNode : public ParserArenaFreeable { public: ParameterNode(JSGlobalData*, const Identifier&); ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&); @@ -1380,11 +1350,11 @@ namespace JSC { ParameterNode* nextParam() const { return m_next; } private: - Identifier m_ident; + const Identifier& m_ident; ParameterNode* m_next; }; - struct ScopeNodeData { + struct ScopeNodeData : FastAllocBase { typedef DeclarationStacks::VarStack VarStack; typedef DeclarationStacks::FunctionStack FunctionStack; @@ -1394,9 +1364,7 @@ namespace JSC { VarStack m_varStack; FunctionStack m_functionStack; int m_numConstants; - StatementVector m_children; - - void mark(); + SourceElements* m_statements; }; class ScopeNode : public StatementNode, public ParserArenaRefCounted { @@ -1407,6 +1375,8 @@ namespace JSC { ScopeNode(JSGlobalData*); ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants); + using ParserArenaRefCounted::operator new; + void adoptData(std::auto_ptr<ScopeNodeData> data) { ASSERT(!data->m_arena.contains(this)); @@ -1432,8 +1402,6 @@ namespace JSC { VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; } - StatementVector& children() { ASSERT(m_data); return m_data->m_children; } - int neededConstants() { ASSERT(m_data); @@ -1442,33 +1410,13 @@ namespace JSC { return m_data->m_numConstants + 2; } - virtual void mark() { } + StatementNode* singleStatement() const; -#if ENABLE(JIT) - JITCode& generatedJITCode() - { - ASSERT(m_jitCode); - return m_jitCode; - } - - ExecutablePool* getExecutablePool() - { - return m_jitCode.getExecutablePool(); - } - - void setJITCode(const JITCode jitCode) - { - m_jitCode = jitCode; - } -#endif + void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); protected: void setSource(const SourceCode& source) { m_source = source; } -#if ENABLE(JIT) - JITCode m_jitCode; -#endif - private: OwnPtr<ScopeNodeData> m_data; CodeFeatures m_features; @@ -1479,190 +1427,101 @@ namespace JSC { public: static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) - { - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = false; private: ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - - OwnPtr<ProgramCodeBlock> m_code; }; class EvalNode : public ScopeNode { public: static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) - { - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - - EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); - - virtual void mark(); - -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = false; private: EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); + }; -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - - OwnPtr<EvalCodeBlock> m_code; + class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> { + public: + static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); } + + private: + FunctionParameters(ParameterNode*); }; class FunctionBodyNode : public ScopeNode { - friend class JIT; public: -#if ENABLE(JIT) - static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*); -#endif static FunctionBodyNode* create(JSGlobalData*); static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); + virtual ~FunctionBodyNode(); - const Identifier* parameters() const { return m_parameters; } - size_t parameterCount() const { return m_parameterCount; } - UString paramString() const ; - Identifier* copyParameters(); + FunctionParameters* parameters() const { return m_parameters.get(); } + size_t parameterCount() const { return m_parameters->size(); } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - bool isGenerated() const - { - return m_code; - } - - bool isHostFunction() const; - - virtual void mark(); - - void finishParsing(const SourceCode&, ParameterNode*); - void finishParsing(Identifier* parameters, size_t parameterCount); + void finishParsing(const SourceCode&, ParameterNode*, const Identifier&); + void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&); - UString toSourceString() const { return source().toString(); } + const Identifier& ident() { return m_ident; } - CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = true; - CodeBlock& bytecode(ScopeChainNode* scopeChain) - { - ASSERT(scopeChain); - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - - CodeBlock& generatedBytecode() - { - ASSERT(m_code); - return *m_code; - } - private: FunctionBodyNode(JSGlobalData*); FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - Identifier* m_parameters; - size_t m_parameterCount; - OwnPtr<CodeBlock> m_code; -#ifdef QT_BUILD_SCRIPT_LIB - SourcePool::SourcePoolToken* sourceToken; -#endif + Identifier m_ident; + RefPtr<FunctionParameters> m_parameters; }; - class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted { + class FuncExprNode : public ExpressionNode { public: FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0); - JSFunction* makeFunction(ExecState*, ScopeChainNode*); - - FunctionBodyNode* body() { return m_body.get(); } + FunctionBodyNode* body() { return m_body; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isFuncExprNode() const { return true; } - Identifier m_ident; - RefPtr<FunctionBodyNode> m_body; + FunctionBodyNode* m_body; }; - class FuncDeclNode : public StatementNode, public ParserArenaRefCounted { + class FuncDeclNode : public StatementNode { public: FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); - JSFunction* makeFunction(ExecState*, ScopeChainNode*); - - Identifier m_ident; - - FunctionBodyNode* body() { return m_body.get(); } + FunctionBodyNode* body() { return m_body; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - RefPtr<FunctionBodyNode> m_body; + FunctionBodyNode* m_body; }; - class CaseClauseNode : public ParserArenaDeletable { + class CaseClauseNode : public ParserArenaFreeable { public: - CaseClauseNode(JSGlobalData*, ExpressionNode*); - CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*); + CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0); ExpressionNode* expr() const { return m_expr; } - StatementVector& children() { return m_children; } + + void emitBytecode(BytecodeGenerator&, RegisterID* destination); private: ExpressionNode* m_expr; - StatementVector m_children; + SourceElements* m_statements; }; - class ClauseListNode : public ParserArenaDeletable { + class ClauseListNode : public ParserArenaFreeable { public: ClauseListNode(JSGlobalData*, CaseClauseNode*); ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*); @@ -1675,11 +1534,11 @@ namespace JSC { ClauseListNode* m_next; }; - class CaseBlockNode : public ParserArenaDeletable { + class CaseBlockNode : public ParserArenaFreeable { public: CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2); - RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0); + RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination); private: SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.cpp index 96f4ae6..4c046d0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.cpp @@ -53,7 +53,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg) *errMsg = 0; Lexer& lexer = *globalData->lexer; - lexer.setCode(*m_source); + lexer.setCode(*m_source, m_arena); int parseError = jscyyparse(globalData); bool lexError = lexer.sawError(); @@ -67,33 +67,6 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg) } } -void Parser::reparseInPlace(JSGlobalData* globalData, FunctionBodyNode* functionBodyNode) -{ - ASSERT(!functionBodyNode->data()); - - m_source = &functionBodyNode->source(); - globalData->lexer->setIsReparsing(); - parse(globalData, 0, 0); - ASSERT(m_sourceElements); - - functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(globalData->parser->arena(), - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - m_numConstants))); - bool usesArguments = functionBodyNode->usesArguments(); - functionBodyNode->setFeatures(m_features); - if (usesArguments && !functionBodyNode->usesArguments()) - functionBodyNode->setUsesArguments(); - - ASSERT(globalData->parser->arena().isEmpty()); - - m_source = 0; - m_sourceElements = 0; - m_varDeclarations = 0; - m_funcDeclarations = 0; -} - void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants) { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h index 5a182a6..7f20480 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h @@ -24,7 +24,11 @@ #define Parser_h #include "Debugger.h" +#include "Executable.h" +#include "JSGlobalObject.h" +#include "Lexer.h" #include "Nodes.h" +#include "ParserArena.h" #include "SourceProvider.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -41,9 +45,8 @@ namespace JSC { class Parser : public Noncopyable { public: - template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); - template <class ParsedNode> PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*); - void reparseInPlace(JSGlobalData*, FunctionBodyNode*); + template <class ParsedNode> + PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, Debugger*, ExecState*, const SourceCode& source, int* errLine = 0, UString* errMsg = 0); void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); @@ -63,47 +66,23 @@ namespace JSC { int m_numConstants; }; - template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg) + template <class ParsedNode> + PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, int* errLine, UString* errMsg) { m_source = &source; - parse(&exec->globalData(), errLine, errMsg); - RefPtr<ParsedNode> result; - if (m_sourceElements) { - result = ParsedNode::create(&exec->globalData(), - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - *m_source, - m_features, - m_numConstants); - int column = m_source->startOffset(); //is it good way to find column number? - result->setLoc(m_source->firstLine(), m_lastLine, column); - } - - m_arena.reset(); + if (ParsedNode::scopeIsFunction) + globalData->lexer->setIsReparsing(); + parse(globalData, errLine, errMsg); - m_source = 0; - m_varDeclarations = 0; - m_funcDeclarations = 0; - - if (debugger) - debugger->sourceParsed(exec, source, *errLine, *errMsg); - return result.release(); - } - - template <class ParsedNode> PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode) - { - m_source = &oldParsedNode->source(); - parse(globalData, 0, 0); RefPtr<ParsedNode> result; if (m_sourceElements) { result = ParsedNode::create(globalData, - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - *m_source, - oldParsedNode->features(), - m_numConstants); + m_sourceElements, + m_varDeclarations ? &m_varDeclarations->data : 0, + m_funcDeclarations ? &m_funcDeclarations->data : 0, + source, + m_features, + m_numConstants); int column = m_source->startOffset(); //is it good way to find column number? result->setLoc(m_source->firstLine(), m_lastLine, column); } @@ -111,9 +90,12 @@ namespace JSC { m_arena.reset(); m_source = 0; + m_sourceElements = 0; m_varDeclarations = 0; m_funcDeclarations = 0; + if (debugger && !ParsedNode::scopeIsFunction) + debugger->sourceParsed(debuggerExecState, source, *errLine, *errMsg); return result.release(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.cpp index 78c5196..6a2af83 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.cpp @@ -31,9 +31,39 @@ namespace JSC { +ParserArena::ParserArena() + : m_freeableMemory(0) + , m_freeablePoolEnd(0) + , m_identifierArena(new IdentifierArena) +{ +} + +inline void* ParserArena::freeablePool() +{ + ASSERT(m_freeablePoolEnd); + return m_freeablePoolEnd - freeablePoolSize; +} + +inline void ParserArena::deallocateObjects() +{ + if (m_freeablePoolEnd) + fastFree(freeablePool()); + + size_t size = m_freeablePools.size(); + for (size_t i = 0; i < size; ++i) + fastFree(m_freeablePools[i]); + + size = m_deletableObjects.size(); + for (size_t i = 0; i < size; ++i) { + ParserArenaDeletable* object = m_deletableObjects[i]; + object->~ParserArenaDeletable(); + fastFree(object); + } +} + ParserArena::~ParserArena() { - deleteAllValues(m_deletableObjects); + deallocateObjects(); } bool ParserArena::contains(ParserArenaRefCounted* object) const @@ -53,26 +83,53 @@ void ParserArena::removeLast() void ParserArena::reset() { - deleteAllValues(m_deletableObjects); - m_deletableObjects.shrink(0); - m_refCountedObjects.shrink(0); + // Since this code path is used only when parsing fails, it's not bothering to reuse + // any of the memory the arena allocated. We could improve that later if we want to + // efficiently reuse the same arena. + + deallocateObjects(); + + m_freeableMemory = 0; + m_freeablePoolEnd = 0; + m_identifierArena->clear(); + m_freeablePools.clear(); + m_deletableObjects.clear(); + m_refCountedObjects.clear(); } -void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData) +void ParserArena::allocateFreeablePool() { - ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size)); - globalData->parser->arena().deleteWithArena(deletable); - return deletable; + if (m_freeablePoolEnd) + m_freeablePools.append(freeablePool()); + + char* pool = static_cast<char*>(fastMalloc(freeablePoolSize)); + m_freeableMemory = pool; + m_freeablePoolEnd = pool + freeablePoolSize; + ASSERT(freeablePool() == pool); } -void* ParserArenaDeletable::operator new(size_t size) +bool ParserArena::isEmpty() const { - return fastMalloc(size); + return !m_freeablePoolEnd + && m_identifierArena->isEmpty() + && m_freeablePools.isEmpty() + && m_deletableObjects.isEmpty() + && m_refCountedObjects.isEmpty(); } -void ParserArenaDeletable::operator delete(void* p) +void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object) +{ + m_refCountedObjects.append(object); +} + +void* ParserArenaFreeable::operator new(size_t size, JSGlobalData* globalData) +{ + return globalData->parser->arena().allocateFreeable(size); +} + +void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData) { - fastFree(p); + return globalData->parser->arena().allocateDeletable(size); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h index 66c8529..2fd4fc1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h @@ -26,35 +26,101 @@ #ifndef ParserArena_h #define ParserArena_h -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> +#include "Identifier.h" +#include <wtf/SegmentedVector.h> namespace JSC { class ParserArenaDeletable; class ParserArenaRefCounted; - class ParserArena { + class IdentifierArena { public: + ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length); + const Identifier& makeNumericIdentifier(JSGlobalData*, double number); + + void clear() { m_identifiers.clear(); } + bool isEmpty() const { return m_identifiers.isEmpty(); } + + private: + typedef SegmentedVector<Identifier, 64> IdentifierVector; + IdentifierVector m_identifiers; + }; + + ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(JSGlobalData* globalData, const UChar* characters, size_t length) + { + m_identifiers.append(Identifier(globalData, characters, length)); + return m_identifiers.last(); + } + + inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number) + { + m_identifiers.append(Identifier(globalData, UString::from(number))); + return m_identifiers.last(); + } + + class ParserArena : Noncopyable { + public: + ParserArena(); + ~ParserArena(); + void swap(ParserArena& otherArena) { + std::swap(m_freeableMemory, otherArena.m_freeableMemory); + std::swap(m_freeablePoolEnd, otherArena.m_freeablePoolEnd); + m_identifierArena.swap(otherArena.m_identifierArena); + m_freeablePools.swap(otherArena.m_freeablePools); m_deletableObjects.swap(otherArena.m_deletableObjects); m_refCountedObjects.swap(otherArena.m_refCountedObjects); } - ~ParserArena(); - void deleteWithArena(ParserArenaDeletable* object) { m_deletableObjects.append(object); } - void derefWithArena(PassRefPtr<ParserArenaRefCounted> object) { m_refCountedObjects.append(object); } + void* allocateFreeable(size_t size) + { + ASSERT(size); + ASSERT(size <= freeablePoolSize); + size_t alignedSize = alignSize(size); + ASSERT(alignedSize <= freeablePoolSize); + if (UNLIKELY(static_cast<size_t>(m_freeablePoolEnd - m_freeableMemory) < alignedSize)) + allocateFreeablePool(); + void* block = m_freeableMemory; + m_freeableMemory += alignedSize; + return block; + } + + void* allocateDeletable(size_t size) + { + ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size)); + m_deletableObjects.append(deletable); + return deletable; + } + void derefWithArena(PassRefPtr<ParserArenaRefCounted>); bool contains(ParserArenaRefCounted*) const; ParserArenaRefCounted* last() const; void removeLast(); - bool isEmpty() const { return m_deletableObjects.isEmpty() && m_refCountedObjects.isEmpty(); } + bool isEmpty() const; void reset(); + IdentifierArena& identifierArena() { return *m_identifierArena; } + private: + static const size_t freeablePoolSize = 8000; + + static size_t alignSize(size_t size) + { + return (size + sizeof(WTF::AllocAlignmentInteger) - 1) & ~(sizeof(WTF::AllocAlignmentInteger) - 1); + } + + void* freeablePool(); + void allocateFreeablePool(); + void deallocateObjects(); + + char* m_freeableMemory; + char* m_freeablePoolEnd; + + OwnPtr<IdentifierArena> m_identifierArena; + Vector<void*> m_freeablePools; Vector<ParserArenaDeletable*> m_deletableObjects; Vector<RefPtr<ParserArenaRefCounted> > m_refCountedObjects; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.cpp deleted file mode 100644 index 4fc859f..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (C) 2008, 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 Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" -#include "SourcePoolQt.h" - - -#ifdef QT_BUILD_SCRIPT_LIB - -#include "SourceCode.h" -#include "Debugger.h" - - -namespace JSC { - - void SourcePool::startEvaluating(const SourceCode& source) - { - int id = source.provider()->asID(); - - codes.insert(id,source.toString()); - - currentScript.push(id); - scriptRef.insert(id,ScriptActivCount()); - - if (debug) - debug->scriptLoad(id,source.toString(),source.provider()->url(),source.firstLine()); - } - - - void SourcePool::stopEvaluating(const SourceCode& source) - { - int id = source.provider()->asID(); - currentScript.pop(); - - if (scriptRef.contains(id)) { - ScriptActivCount info = scriptRef.take(id); - if (info.getCount()) { - //we can't remove info from scriptRef - info.isActive = false; - scriptRef.insert(id,info); - } else { - //we are unloading source code - if (debug) - debug->scriptUnload(id); - } - } - } - - SourcePool::SourcePoolToken* SourcePool::objectRegister() - { - if (currentScript.isEmpty()) { - return 0; - } - - int id = currentScript.top(); - - SourcePoolToken* token = new SourcePoolToken(id,this); - - ScriptActivCount info = scriptRef.take(id); - - info.incCount(); - scriptRef.insert(id,info); - return token; - } - - void SourcePool::objectUnregister(const SourcePool::SourcePoolToken *token) - { - int id = token->id; - - ScriptActivCount info = scriptRef.take(id); - info.decCount(); - if (info.isActive) { - scriptRef.insert(id,info); - } else { - if (info.getCount() == 0) { - //remove from scriptRef (script is not active and there is no objects connected) - if(debug) - debug->scriptUnload(id); - } else { - scriptRef.insert(id,info); - } - } - - } - - - void SourcePool::setDebugger(JSC::Debugger *debugger) { this->debug = debugger; } - Debugger* SourcePool::debugger() { return debug; } - -} //namespace JSC - - -#endif //QT_BUILD_SCRIPT_LIB diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.h deleted file mode 100644 index da58edb..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourcePoolQt.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2008, 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 Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef SOURCEPOOL_H -#define SOURCEPOOL_H - -#ifdef QT_BUILD_SCRIPT_LIB - -#include "qhash.h" -#include "qstack.h" -#include "qdebug.h" -#include <stdint.h> - -namespace JSC { - - QT_USE_NAMESPACE - - class SourceCode; - class Debugger; - - class SourcePool - { - class ScriptActivCount - { - int count; - public: - void incCount() - { - count++; - }; - void decCount() - { - count--; - }; - int getCount() const - { - return count; - }; - bool isActive; - ScriptActivCount() : count(0), isActive(true) {} - }; - QStack<intptr_t> currentScript; - QHash<unsigned, ScriptActivCount> scriptRef; - QHash<int, QString> codes; //debug - Debugger *debug; - - friend class SourcePoolToken; - public: - class SourcePoolToken - { - unsigned id; - SourcePool *ptr; - SourcePoolToken(unsigned scriptId, SourcePool *scriptPool) : id(scriptId),ptr(scriptPool) {} - SourcePoolToken(const SourcePoolToken&) : id(0), ptr(0) {} //private - do not use - will crash - public: - ~SourcePoolToken() { ptr->objectUnregister(this); } - friend class SourcePool; - }; - - SourcePool() : debug(0) {} - - void startEvaluating(const SourceCode& source); - void stopEvaluating(const SourceCode& source); - SourcePoolToken* objectRegister(); - - void setDebugger(Debugger *debugger); - Debugger* debugger(); - - private: - void objectUnregister(const SourcePoolToken *token); - }; - -} //namespace JSC - - -#endif //QT_BUILD_SCRIPT_LIB - -#endif // SOURCEPOOL_H diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceProvider.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceProvider.h index 1c59eed..cc605ca 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceProvider.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceProvider.h @@ -70,7 +70,11 @@ namespace JSC { const UChar* data() const { return m_source.data(); } int length() const { return m_source.size(); } +#ifdef QT_BUILD_SCRIPT_LIB + protected: +#else private: +#endif UStringSourceProvider(const UString& source, const UString& url) : SourceProvider(url) , m_source(source) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables index 8a2d140..1f0ea01 100755 --- a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables +++ b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables @@ -244,7 +244,7 @@ sub readHeaderValues() my ($fh, $tempFile) = tempfile( basename($0) . "-XXXXXXXX", - DIR => File::Spec->tmpdir, + DIR => File::Spec->tmpdir(), SUFFIX => ".in", UNLINK => 0, ); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp index 1a061cb..dc68ecb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp @@ -27,6 +27,7 @@ #include "ProfileGenerator.h" #include "CallFrame.h" +#include "CodeBlock.h" #include "JSGlobalObject.h" #include "JSStringRef.h" #include "JSFunction.h" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.h index cccb502..82149b3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.h @@ -33,11 +33,11 @@ namespace JSC { - class CallIdentifier; class ExecState; class Profile; class ProfileNode; class UString; + struct CallIdentifier; class ProfileGenerator : public RefCounted<ProfileGenerator> { public: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp index e103fd1..6f72e08 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp @@ -31,6 +31,7 @@ #include "CommonIdentifiers.h" #include "CallFrame.h" +#include "CodeBlock.h" #include "JSFunction.h" #include "JSGlobalObject.h" #include "Nodes.h" @@ -134,26 +135,27 @@ void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startin dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), JSValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup()); } -CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue function, const UString& defaultSourceURL, int defaultLineNumber) +CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue functionValue, const UString& defaultSourceURL, int defaultLineNumber) { - if (!function) + if (!functionValue) return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber); - if (!function.isObject()) + if (!functionValue.isObject()) return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber); - if (asObject(function)->inherits(&JSFunction::info)) { - JSFunction* func = asFunction(function); - if (!func->isHostFunction()) - return createCallIdentifierFromFunctionImp(globalData, func); + if (asObject(functionValue)->inherits(&JSFunction::info)) { + JSFunction* function = asFunction(functionValue); + if (!function->executable()->isHostFunction()) + return createCallIdentifierFromFunctionImp(globalData, function); } - if (asObject(function)->inherits(&InternalFunction::info)) - return CallIdentifier(static_cast<InternalFunction*>(asObject(function))->name(globalData), defaultSourceURL, defaultLineNumber); - return CallIdentifier("(" + asObject(function)->className() + " object)", defaultSourceURL, defaultLineNumber); + if (asObject(functionValue)->inherits(&InternalFunction::info)) + return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(globalData), defaultSourceURL, defaultLineNumber); + return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber); } CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData* globalData, JSFunction* function) { + ASSERT(!function->isHostFunction()); const UString& name = function->calculatedDisplayName(globalData); - return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->body()->sourceURL(), function->body()->lineNo()); + return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->jsExecutable()->sourceURL(), function->jsExecutable()->lineNo()); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h index 869f419..21621bf 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h @@ -36,13 +36,13 @@ namespace JSC { - class CallIdentifier; class ExecState; class JSGlobalData; class JSObject; class JSValue; class ProfileGenerator; class UString; + struct CallIdentifier; class Profiler : public FastAllocBase { public: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp index 0b5d958..ab2b5d7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -37,16 +37,12 @@ void ArgList::getSlice(int startIndex, ArgList& result) const result = ArgList(m_args + startIndex, m_argCount - startIndex); } -void MarkedArgumentBuffer::markLists(ListSet& markSet) +void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet) { ListSet::iterator end = markSet.end(); for (ListSet::iterator it = markSet.begin(); it != end; ++it) { MarkedArgumentBuffer* list = *it; - - iterator end2 = list->end(); - for (iterator it2 = list->begin(); it2 != end2; ++it2) - if (!(*it2).marked()) - (*it2).mark(); + markStack.appendValues(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h index 0899e85..3227770 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Computer, Inc. + * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,15 +22,15 @@ #ifndef ArgList_h #define ArgList_h -#include "JSImmediate.h" #include "Register.h" - #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> #include <wtf/Vector.h> namespace JSC { - + + class MarkStack; + class MarkedArgumentBuffer : public Noncopyable { private: static const unsigned inlineCapacity = 8; @@ -136,7 +136,7 @@ namespace JSC { const_iterator begin() const { return m_buffer; } const_iterator end() const { return m_buffer + m_size; } - static void markLists(ListSet&); + static void markLists(MarkStack&, ListSet&); private: void slowAppend(JSValue); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp index 7cb4fe9..d90ea15 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * @@ -43,30 +43,22 @@ Arguments::~Arguments() delete [] d->extraArguments; } -void Arguments::mark() +void Arguments::markChildren(MarkStack& markStack) { - JSObject::mark(); + JSObject::markChildren(markStack); - if (d->registerArray) { - for (unsigned i = 0; i < d->numParameters; ++i) { - if (!d->registerArray[i].marked()) - d->registerArray[i].mark(); - } - } + if (d->registerArray) + markStack.appendValues(reinterpret_cast<JSValue*>(d->registerArray.get()), d->numParameters); if (d->extraArguments) { unsigned numExtraArguments = d->numArguments - d->numParameters; - for (unsigned i = 0; i < numExtraArguments; ++i) { - if (!d->extraArguments[i].marked()) - d->extraArguments[i].mark(); - } + markStack.appendValues(reinterpret_cast<JSValue*>(d->extraArguments), numExtraArguments); } - if (!d->callee->marked()) - d->callee->mark(); + markStack.append(d->callee); - if (d->activation && !d->activation->marked()) - d->activation->mark(); + if (d->activation) + markStack.append(d->activation); } void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) @@ -187,6 +179,31 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa return JSObject::getOwnPropertySlot(exec, propertyName, slot); } +bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + bool isArrayIndex; + unsigned i = propertyName.toArrayIndex(&isArrayIndex); + if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { + if (i < d->numParameters) { + descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum); + } else + descriptor.setDescriptor(d->extraArguments[i - d->numParameters].jsValue(), DontEnum); + return true; + } + + if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { + descriptor.setDescriptor(jsNumber(exec, d->numArguments), DontEnum); + return true; + } + + if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { + descriptor.setDescriptor(d->callee, DontEnum); + return true; + } + + return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot) { if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h index dc54dac..2aa0921 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * @@ -28,6 +28,8 @@ #include "JSFunction.h" #include "JSGlobalObject.h" #include "Interpreter.h" +#include "ObjectConstructor.h" +#include "PrototypeFunction.h" namespace JSC { @@ -61,7 +63,7 @@ namespace JSC { static const ClassInfo info; - virtual void mark(); + virtual void markChildren(MarkStack&); void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -90,6 +92,7 @@ namespace JSC { void getArgumentsData(CallFrame*, JSObject*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); @@ -116,21 +119,20 @@ namespace JSC { callee = callFrame->callee(); int numParameters; - if (callee->isObject(&JSFunction::info)) { - CodeBlock* codeBlock = &JSC::asFunction(callee)->body()->generatedBytecode(); - numParameters = codeBlock->m_numParameters; - } else { + if (callee->inherits(&JSFunction::info)) + numParameters = JSC::asFunction(callee)->jsExecutable()->parameterCount(); + else numParameters = 0; - } + argc = callFrame->argumentCount(); if (argc <= numParameters) - argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this" + argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters; else - argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc + 1; // + 1 to skip "this" + argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc; argc -= 1; // - 1 to skip "this" - firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this" + firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters; } inline Arguments::Arguments(CallFrame* callFrame) @@ -143,8 +145,8 @@ namespace JSC { int numArguments; getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments); - if (callee->isObject(&JSFunction::info)) - d->numParameters = JSC::asFunction(callee)->body()->parameterCount(); + if (callee->inherits(&JSFunction::info)) + d->numParameters = JSC::asFunction(callee)->jsExecutable()->parameterCount(); else d->numParameters = 0; d->firstParameterIndex = firstParameterIndex; @@ -177,8 +179,8 @@ namespace JSC { : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure()) , d(new ArgumentsData) { - if (callFrame->callee() && callFrame->callee()->isObject(&JSC::JSFunction::info)) - ASSERT(!asFunction(callFrame->callee())->body()->parameterCount()); + if (callFrame->callee() && callFrame->callee()->inherits(&JSC::JSFunction::info)) + ASSERT(!asFunction(callFrame->callee())->jsExecutable()->parameterCount()); unsigned numArguments = callFrame->argumentCount() - 1; @@ -193,7 +195,7 @@ namespace JSC { extraArguments = d->extraArgumentsFixedBuffer; Register* argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numArguments - 1; - if (callFrame->callee() && !callFrame->callee()->isObject(&JSC::JSFunction::info)) + if (callFrame->callee() && !callFrame->callee()->inherits(&JSC::JSFunction::info)) ++argv; // ### off-by-one issue with native functions for (unsigned i = 0; i < numArguments; ++i) extraArguments[i] = argv[i]; @@ -226,8 +228,8 @@ namespace JSC { { ASSERT(!d()->registerArray); - size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1; - size_t numVars = d()->functionBody->generatedBytecode().m_numVars; + size_t numParametersMinusThis = d()->functionExecutable->generatedBytecode().m_numParameters - 1; + size_t numVars = d()->functionExecutable->generatedBytecode().m_numVars; size_t numLocals = numVars + numParametersMinusThis; if (!numLocals) @@ -242,6 +244,14 @@ namespace JSC { static_cast<Arguments*>(arguments)->setActivation(this); } + ALWAYS_INLINE Arguments* Register::arguments() const + { + if (jsValue() == JSValue()) + return 0; + return asArguments(jsValue()); + } + + } // namespace JSC #endif // Arguments_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp index e96bdfc..c60cb0e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -25,15 +25,19 @@ #include "ArrayConstructor.h" #include "ArrayPrototype.h" +#include "Error.h" #include "JSArray.h" #include "JSFunction.h" #include "Lookup.h" +#include "PrototypeFunction.h" namespace JSC { ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor); + +static JSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*, JSObject*, JSValue, const ArgList&); -ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype) +ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* prototypeFunctionStructure) : InternalFunction(&exec->globalData(), structure, Identifier(exec, arrayPrototype->classInfo()->className)) { // ECMA 15.4.3.1 Array.prototype @@ -41,6 +45,9 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> struct // no. of arguments for constructor putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete); + + // ES5 + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum); } static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) @@ -82,4 +89,9 @@ CallType ArrayConstructor::getCallData(CallData& callData) return CallTypeHost; } +JSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*, JSObject*, JSValue, const ArgList& args) +{ + return jsBoolean(args.at(0).inherits(&JSArray::info)); +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h index 8300d8c..2b79510 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h @@ -29,7 +29,7 @@ namespace JSC { class ArrayConstructor : public InternalFunction { public: - ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*); + ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*, Structure*); virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp index 807e59a..e1b1f34 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -67,7 +67,7 @@ static JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JS namespace JSC { -static inline bool isNumericCompareFunction(CallType callType, const CallData& callData) +static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData) { if (callType != CallTypeJS) return false; @@ -75,10 +75,10 @@ static inline bool isNumericCompareFunction(CallType callType, const CallData& c #if ENABLE(JIT) // If the JIT is enabled then we need to preserve the invariant that every // function with a CodeBlock also has JIT code. - callData.js.functionBody->jitCode(callData.js.scopeChain); - CodeBlock& codeBlock = callData.js.functionBody->generatedBytecode(); + callData.js.functionExecutable->jitCode(exec, callData.js.scopeChain); + CodeBlock& codeBlock = callData.js.functionExecutable->generatedBytecode(); #else - CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain); + CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(exec, callData.js.scopeChain); #endif return codeBlock.isNumericCompareFunction(); @@ -125,6 +125,11 @@ bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prope return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, slot); } +bool ArrayPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticFunctionDescriptor<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, descriptor); +} + // ------------------------------ Array Functions ---------------------------- // Helper function @@ -144,7 +149,7 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&JSArray::info)) + if (!thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); JSObject* thisObj = asArray(thisValue); @@ -190,7 +195,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&JSArray::info)) + if (!thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); JSObject* thisObj = asArray(thisValue); @@ -298,7 +303,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue t ArgList::const_iterator it = args.begin(); ArgList::const_iterator end = args.end(); while (1) { - if (curArg.isObject(&JSArray::info)) { + if (curArg.inherits(&JSArray::info)) { unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec); JSObject* curObject = curArg.toObject(exec); for (unsigned k = 0; k < length; ++k) { @@ -456,7 +461,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue thi CallType callType = function.getCallData(callData); if (thisObj->classInfo() == &JSArray::info) { - if (isNumericCompareFunction(callType, callData)) + if (isNumericCompareFunction(exec, callType, callData)) asArray(thisObj)->sortNumeric(exec, function, callType, callData); else if (callType != CallTypeNone) asArray(thisObj)->sort(exec, function, callType, callData); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h index 2165089..6f7ed12 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h @@ -31,6 +31,7 @@ namespace JSC { explicit ArrayPrototype(PassRefPtr<Structure>); bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h index b9f738f..929a5e7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h @@ -38,7 +38,7 @@ namespace JSC { : m_object(object) { if (!m_object->structure()->isDictionary()) - m_object->setStructure(Structure::toDictionaryTransition(m_object->structure())); + m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure())); } ~BatchedTransitionOptimizer() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h index cfd55fe..5f3e5f0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h @@ -31,6 +31,11 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + } }; BooleanObject* asBooleanObject(JSValue); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp index 703a568..cf4fbd7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -59,7 +59,7 @@ JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec, JSObject*, JSVal if (thisValue == jsBoolean(true)) return jsNontrivialString(exec, "true"); - if (!thisValue.isObject(&BooleanObject::info)) + if (!thisValue.inherits(&BooleanObject::info)) return throwError(exec, TypeError); if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false)) @@ -74,7 +74,7 @@ JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValu if (thisValue.isBoolean()) return thisValue; - if (!thisValue.isObject(&BooleanObject::info)) + if (!thisValue.inherits(&BooleanObject::info)) return throwError(exec, TypeError); return asBooleanObject(thisValue)->internalValue(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h index 541779c..ef4988b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h @@ -35,7 +35,7 @@ namespace JSC { class ArgList; class ExecState; - class FunctionBodyNode; + class FunctionExecutable; class JSObject; class JSValue; class ScopeChainNode; @@ -79,7 +79,7 @@ namespace JSC { #endif } native; struct { - FunctionBodyNode* functionBody; + FunctionExecutable* functionExecutable; ScopeChainNode* scopeChain; } js; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h index 097fb09..acec4e7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h @@ -27,7 +27,7 @@ namespace JSC { - struct HashEntry; + class HashEntry; struct HashTable; struct ClassInfo { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp index d7fbce8..3784da8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * * This library is free software; you can redistribute it and/or @@ -23,16 +23,20 @@ #include "ArgList.h" #include "CallFrame.h" +#include "CodeBlock.h" #include "CollectorHeapIterator.h" #include "Interpreter.h" +#include "JSArray.h" #include "JSGlobalObject.h" #include "JSLock.h" #include "JSONObject.h" #include "JSString.h" #include "JSValue.h" +#include "MarkStack.h" #include "Nodes.h" #include "Tracing.h" #include <algorithm> +#include <limits.h> #include <setjmp.h> #include <stdlib.h> #include <wtf/FastMalloc.h> @@ -56,28 +60,19 @@ #elif PLATFORM(WIN_OS) #include <windows.h> +#include <malloc.h> + +#elif PLATFORM(HAIKU) + +#include <OS.h> #elif PLATFORM(UNIX) #include <stdlib.h> +#if !PLATFORM(HAIKU) #include <sys/mman.h> -#include <unistd.h> - -#if defined(QT_LINUXBASE) -#include <dlfcn.h> -#endif - -#if defined(__UCLIBC__) -// versions of uClibc 0.9.28 and below do not have -// pthread_getattr_np or pthread_attr_getstack. -#if __UCLIBC_MAJOR__ == 0 && \ - (__UCLIBC_MINOR__ < 9 || \ - (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 30)) -#define UCLIBC_USE_PROC_SELF_MAPS 1 -#include <stdio_ext.h> -extern int *__libc_stack_end; -#endif #endif +#include <unistd.h> #if PLATFORM(SOLARIS) #include <thread.h> @@ -98,7 +93,6 @@ extern int *__libc_stack_end; #endif -#define DEBUG_COLLECTOR 0 #define COLLECT_ON_EVERY_ALLOCATION 0 using std::max; @@ -107,7 +101,6 @@ namespace JSC { // tunable parameters -const size_t SPARE_EMPTY_BLOCKS = 2; const size_t GROWTH_FACTOR = 2; const size_t LOW_WATER_FACTOR = 4; const size_t ALLOCATIONS_PER_COLLECTION = 4000; @@ -120,8 +113,6 @@ const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB static RHeap* userChunk = 0; #endif -static void freeHeap(CollectorHeap*); - #if ENABLE(JSC_MULTIPLE_THREADS) #if PLATFORM(DARWIN) @@ -210,8 +201,8 @@ void Heap::destroy() ASSERT(!primaryHeap.numLiveObjects); - freeHeap(&primaryHeap); - freeHeap(&numberHeap); + freeBlocks(&primaryHeap); + freeBlocks(&numberHeap); #if ENABLE(JSC_MULTIPLE_THREADS) if (m_currentThreadRegistrar) { @@ -231,7 +222,7 @@ void Heap::destroy() } template <HeapType heapType> -static NEVER_INLINE CollectorBlock* allocateBlock() +NEVER_INLINE CollectorBlock* Heap::allocateBlock() { // Disable the use of vm_map for the Qt build on Darwin, because when compiled on 10.4 // it crashes on 10.5 @@ -247,9 +238,15 @@ static NEVER_INLINE CollectorBlock* allocateBlock() uintptr_t address = reinterpret_cast<uintptr_t>(mask); memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE); +#elif PLATFORM(WINCE) + void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #elif PLATFORM(WIN_OS) - // windows virtual address granularity is naturally 64k - LPVOID address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#if COMPILER(MINGW) + void* address = __mingw_aligned_malloc(BLOCK_SIZE, BLOCK_SIZE); +#else + void* address = _aligned_malloc(BLOCK_SIZE, BLOCK_SIZE); +#endif + memset(address, 0, BLOCK_SIZE); #elif HAVE(POSIX_MEMALIGN) void* address; posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE); @@ -281,11 +278,45 @@ static NEVER_INLINE CollectorBlock* allocateBlock() address += adjust; memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE); #endif - reinterpret_cast<CollectorBlock*>(address)->type = heapType; - return reinterpret_cast<CollectorBlock*>(address); + + CollectorBlock* block = reinterpret_cast<CollectorBlock*>(address); + block->freeList = block->cells; + block->heap = this; + block->type = heapType; + + CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; + size_t numBlocks = heap.numBlocks; + if (heap.usedBlocks == numBlocks) { + static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR; + if (numBlocks > maxNumBlocks) + CRASH(); + numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR); + heap.numBlocks = numBlocks; + heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*))); + } + heap.blocks[heap.usedBlocks++] = block; + + return block; +} + +template <HeapType heapType> +NEVER_INLINE void Heap::freeBlock(size_t block) +{ + CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; + + freeBlock(heap.blocks[block]); + + // swap with the last block so we compact as we go + heap.blocks[block] = heap.blocks[heap.usedBlocks - 1]; + heap.usedBlocks--; + + if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) { + heap.numBlocks = heap.numBlocks / GROWTH_FACTOR; + heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*))); + } } -static void freeBlock(CollectorBlock* block) +NEVER_INLINE void Heap::freeBlock(CollectorBlock* block) { // Disable the use of vm_deallocate for the Qt build on Darwin, because when compiled on 10.4 // it crashes on 10.5 @@ -293,8 +324,14 @@ static void freeBlock(CollectorBlock* block) vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE); #elif PLATFORM(SYMBIAN) userChunk->Free(reinterpret_cast<TAny*>(block)); -#elif PLATFORM(WIN_OS) +#elif PLATFORM(WINCE) VirtualFree(block, 0, MEM_RELEASE); +#elif PLATFORM(WIN_OS) +#if COMPILER(MINGW) + __mingw_aligned_free(block); +#else + _aligned_free(block); +#endif #elif HAVE(POSIX_MEMALIGN) free(block); #else @@ -302,7 +339,7 @@ static void freeBlock(CollectorBlock* block) #endif } -static void freeHeap(CollectorHeap* heap) +void Heap::freeBlocks(CollectorHeap* heap) { for (size_t i = 0; i < heap->usedBlocks; ++i) if (heap->blocks[i]) @@ -395,38 +432,23 @@ collect: #ifndef NDEBUG heap.operationInProgress = NoOperation; #endif - bool collected = collect(); + bool foundGarbage = collect(); + numLiveObjects = heap.numLiveObjects; + usedBlocks = heap.usedBlocks; + i = heap.firstBlockWithPossibleSpace; #ifndef NDEBUG heap.operationInProgress = Allocation; #endif - if (collected) { - numLiveObjects = heap.numLiveObjects; - usedBlocks = heap.usedBlocks; - i = heap.firstBlockWithPossibleSpace; + if (foundGarbage) goto scan; - } - } - - // didn't find a block, and GC didn't reclaim anything, need to allocate a new block - size_t numBlocks = heap.numBlocks; - if (usedBlocks == numBlocks) { - static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR; - if (numBlocks > maxNumBlocks) - CRASH(); - numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR); - heap.numBlocks = numBlocks; - heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*))); } + // didn't find a block, and GC didn't reclaim anything, need to allocate a new block targetBlock = reinterpret_cast<Block*>(allocateBlock<heapType>()); - targetBlock->freeList = targetBlock->cells; - targetBlock->heap = this; + heap.firstBlockWithPossibleSpace = heap.usedBlocks - 1; targetBlockUsedCells = 0; - heap.blocks[usedBlocks] = reinterpret_cast<CollectorBlock*>(targetBlock); - heap.usedBlocks = usedBlocks + 1; - heap.firstBlockWithPossibleSpace = usedBlocks; } - + // find a free spot in the block and detach it from the free list Cell* newCell = targetBlock->freeList; @@ -554,6 +576,33 @@ static void *hpux_get_stack_base() } #endif +#if PLATFORM(QNX) +static inline void *currentThreadStackBaseQNX() +{ + static void* stackBase = 0; + static size_t stackSize = 0; + static pthread_t stackThread; + pthread_t thread = pthread_self(); + if (stackBase == 0 || thread != stackThread) { + struct _debug_thread_info threadInfo; + memset(&threadInfo, 0, sizeof(threadInfo)); + threadInfo.tid = pthread_self(); + int fd = open("/proc/self", O_RDONLY); + if (fd == -1) { + LOG_ERROR("Unable to open /proc/self (errno: %d)", errno); + return 0; + } + devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0); + close(fd); + stackBase = reinterpret_cast<void*>(threadInfo.stkbase); + stackSize = threadInfo.stksize; + ASSERT(stackBase); + stackThread = thread; + } + return static_cast<char*>(stackBase) + stackSize; +} +#endif + static inline void* currentThreadStackBase() { #if PLATFORM(DARWIN) @@ -579,6 +628,8 @@ static inline void* currentThreadStackBase() : "=r" (pTib) ); return static_cast<void*>(pTib->StackBase); +#elif PLATFORM(QNX) + return currentThreadStackBaseQNX(); #elif PLATFORM(HPUX) return hpux_get_stack_base(); #elif PLATFORM(SOLARIS) @@ -611,77 +662,21 @@ static inline void* currentThreadStackBase() stackBase = (void*)info.iBase; } return (void*)stackBase; +#elif PLATFORM(HAIKU) + thread_info threadInfo; + get_thread_info(find_thread(NULL), &threadInfo); + return threadInfo.stack_end; #elif PLATFORM(UNIX) -#ifdef UCLIBC_USE_PROC_SELF_MAPS - // Read /proc/self/maps and locate the line whose address - // range contains __libc_stack_end. - FILE *file = fopen("/proc/self/maps", "r"); - if (!file) - return 0; - __fsetlocking(file, FSETLOCKING_BYCALLER); - char *line = NULL; - size_t lineLen = 0; - while (!feof_unlocked(file)) { - if (getdelim(&line, &lineLen, '\n', file) <= 0) - break; - - long from; - long to; - if (sscanf (line, "%lx-%lx", &from, &to) != 2) - continue; - if (from <= (long)__libc_stack_end && (long)__libc_stack_end < to) { - fclose(file); - free(line); -#ifdef _STACK_GROWS_UP - return (void *)from; -#else - return (void *)to; -#endif - } - } - fclose(file); - free(line); - return 0; -#else static void* stackBase = 0; static size_t stackSize = 0; static pthread_t stackThread; pthread_t thread = pthread_self(); if (stackBase == 0 || thread != stackThread) { -#if PLATFORM(QNX) - int fd; - struct _debug_thread_info tinfo; - memset(&tinfo, 0, sizeof(tinfo)); - tinfo.tid = pthread_self(); - fd = open("/proc/self", O_RDONLY); - if (fd == -1) { -#ifndef NDEBUG - perror("Unable to open /proc/self:"); -#endif - return 0; - } - devctl(fd, DCMD_PROC_TIDSTATUS, &tinfo, sizeof(tinfo), NULL); - close(fd); - stackBase = (void*)tinfo.stkbase; - stackSize = tinfo.stksize; - ASSERT(stackBase); -#else -#if defined(QT_LINUXBASE) - // LinuxBase is missing pthread_getattr_np - resolve it once at runtime instead - // see http://bugs.linuxbase.org/show_bug.cgi?id=2364 - typedef int (*GetAttrPtr)(pthread_t, pthread_attr_t *); - static int (*pthread_getattr_np_ptr)(pthread_t, pthread_attr_t *) = 0; - if (!pthread_getattr_np_ptr) - *(void **)&pthread_getattr_np_ptr = dlsym(RTLD_DEFAULT, "pthread_getattr_np"); -#endif pthread_attr_t sattr; pthread_attr_init(&sattr); #if HAVE(PTHREAD_NP_H) || PLATFORM(NETBSD) // e.g. on FreeBSD 5.4, neundorf@kde.org pthread_attr_get_np(thread, &sattr); -#elif defined(QT_LINUXBASE) - if (pthread_getattr_np_ptr) - pthread_getattr_np_ptr(thread, &sattr); #else // FIXME: this function is non-portable; other POSIX systems may have different np alternatives pthread_getattr_np(thread, &sattr); @@ -690,11 +685,9 @@ static inline void* currentThreadStackBase() (void)rc; // FIXME: Deal with error code somehow? Seems fatal. ASSERT(stackBase); pthread_attr_destroy(&sattr); -#endif stackThread = thread; } return static_cast<char*>(stackBase) + stackSize; -#endif #elif PLATFORM(WINCE) if (g_stackBase) return g_stackBase; @@ -731,6 +724,8 @@ void Heap::makeUsableFromMultipleThreads() void Heap::registerThread() { + ASSERT(!m_globalData->mainThreadOnly || isMainThread()); + if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar)) return; @@ -787,7 +782,7 @@ void Heap::registerThread() // cell size needs to be a power of two for this to be valid #define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0) -void Heap::markConservatively(void* start, void* end) +void Heap::markConservatively(MarkStack& markStack, void* start, void* end) { if (start > end) { void* tmp = start; @@ -827,10 +822,9 @@ void Heap::markConservatively(void* start, void* end) // Mark the primary heap for (size_t block = 0; block < usedPrimaryBlocks; block++) { if ((primaryBlocks[block] == blockAddr) & (offset <= lastCellOffset)) { - if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree != 0) { - JSCell* imp = reinterpret_cast<JSCell*>(xAsBits); - if (!imp->marked()) - imp->mark(); + if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree) { + markStack.append(reinterpret_cast<JSCell*>(xAsBits)); + markStack.drain(); } break; } @@ -841,15 +835,15 @@ void Heap::markConservatively(void* start, void* end) } } -void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal() +void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markStack) { void* dummy; void* stackPointer = &dummy; void* stackBase = currentThreadStackBase(); - markConservatively(stackPointer, stackBase); + markConservatively(markStack, stackPointer, stackBase); } -void Heap::markCurrentThreadConservatively() +void Heap::markCurrentThreadConservatively(MarkStack& markStack) { // setjmp forces volatile registers onto the stack jmp_buf registers; @@ -862,7 +856,7 @@ void Heap::markCurrentThreadConservatively() #pragma warning(pop) #endif - markCurrentThreadConservativelyInternal(); + markCurrentThreadConservativelyInternal(markStack); } #if ENABLE(JSC_MULTIPLE_THREADS) @@ -994,7 +988,7 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) #endif } -void Heap::markOtherThreadConservatively(Thread* thread) +void Heap::markOtherThreadConservatively(MarkStack& markStack, Thread* thread) { suspendThread(thread->platformThread); @@ -1002,19 +996,19 @@ void Heap::markOtherThreadConservatively(Thread* thread) size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs); // mark the thread's registers - markConservatively(static_cast<void*>(®s), static_cast<void*>(reinterpret_cast<char*>(®s) + regSize)); + markConservatively(markStack, static_cast<void*>(®s), static_cast<void*>(reinterpret_cast<char*>(®s) + regSize)); void* stackPointer = otherThreadStackPointer(regs); - markConservatively(stackPointer, thread->stackBase); + markConservatively(markStack, stackPointer, thread->stackBase); resumeThread(thread->platformThread); } #endif -void Heap::markStackObjectsConservatively() +void Heap::markStackObjectsConservatively(MarkStack& markStack) { - markCurrentThreadConservatively(); + markCurrentThreadConservatively(markStack); #if ENABLE(JSC_MULTIPLE_THREADS) @@ -1024,7 +1018,7 @@ void Heap::markStackObjectsConservatively() #ifndef NDEBUG // Forbid malloc during the mark phase. Marking a thread suspends it, so - // a malloc inside mark() would risk a deadlock with a thread that had been + // a malloc inside markChildren() would risk a deadlock with a thread that had been // suspended while holding the malloc lock. fastMallocForbid(); #endif @@ -1032,7 +1026,7 @@ void Heap::markStackObjectsConservatively() // and since this is a shared heap, they are real locks. for (Thread* thread = m_registeredThreads; thread; thread = thread->next) { if (!pthread_equal(thread->posixThread, pthread_self())) - markOtherThreadConservatively(thread); + markOtherThreadConservatively(markStack, thread); } #ifndef NDEBUG fastMallocAllow(); @@ -1085,23 +1079,15 @@ void Heap::unprotect(JSValue k) m_protectedValuesMutex->unlock(); } -Heap* Heap::heap(JSValue v) -{ - if (!v.isCell()) - return 0; - return Heap::cellBlock(v.asCell())->heap; -} - -void Heap::markProtectedObjects() +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) { - JSCell* val = it->first; - if (!val->marked()) - val->mark(); + markStack.append(it->first); + markStack.drain(); } if (m_protectedValuesMutex) @@ -1179,34 +1165,37 @@ template <HeapType heapType> size_t Heap::sweep() curBlock->freeList = freeList; curBlock->marked.clearAll(); - if (usedCells == 0) { - emptyBlocks++; - if (emptyBlocks > SPARE_EMPTY_BLOCKS) { -#if !DEBUG_COLLECTOR - freeBlock(reinterpret_cast<CollectorBlock*>(curBlock)); -#endif - // swap with the last block so we compact as we go - heap.blocks[block] = heap.blocks[heap.usedBlocks - 1]; - heap.usedBlocks--; - block--; // Don't move forward a step in this case - - if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) { - heap.numBlocks = heap.numBlocks / GROWTH_FACTOR; - heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*))); - } - } - } + if (!usedCells) + ++emptyBlocks; } if (heap.numLiveObjects != numLiveObjects) heap.firstBlockWithPossibleSpace = 0; - + heap.numLiveObjects = numLiveObjects; heap.numLiveObjectsAtLastCollect = numLiveObjects; heap.extraCost = 0; + + if (!emptyBlocks) + return numLiveObjects; + + size_t neededCells = 1.25f * (numLiveObjects + max(ALLOCATIONS_PER_COLLECTION, numLiveObjects)); + size_t neededBlocks = (neededCells + HeapConstants<heapType>::cellsPerBlock - 1) / HeapConstants<heapType>::cellsPerBlock; + for (size_t block = 0; block < heap.usedBlocks; block++) { + if (heap.usedBlocks <= neededBlocks) + break; + + Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]); + if (curBlock->usedCells) + continue; + + freeBlock<heapType>(block); + block--; // Don't move forward a step in this case + } + return numLiveObjects; } - + bool Heap::collect() { #ifndef NDEBUG @@ -1225,24 +1214,26 @@ bool Heap::collect() numberHeap.operationInProgress = Collection; // MARK: first mark all referenced objects recursively starting out from the set of root objects - - markStackObjectsConservatively(); - markProtectedObjects(); + MarkStack& markStack = m_globalData->markStack; + markStackObjectsConservatively(markStack); + markProtectedObjects(markStack); #if QT_BUILD_SCRIPT_LIB if (m_globalData->clientData) - m_globalData->clientData->mark(); + m_globalData->clientData->mark(markStack); #endif if (m_markListSet && m_markListSet->size()) - MarkedArgumentBuffer::markLists(*m_markListSet); - if (m_globalData->exception && !m_globalData->exception.marked()) - m_globalData->exception.mark(); - m_globalData->interpreter->registerFile().markCallFrames(this); - m_globalData->smallStrings.mark(); - if (m_globalData->scopeNodeBeingReparsed) - m_globalData->scopeNodeBeingReparsed->mark(); + MarkedArgumentBuffer::markLists(markStack, *m_markListSet); + if (m_globalData->exception) + markStack.append(m_globalData->exception); + m_globalData->interpreter->registerFile().markCallFrames(markStack, this); + m_globalData->smallStrings.markChildren(markStack); + if (m_globalData->functionCodeBlockBeingReparsed) + m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack); if (m_globalData->firstStringifierToMark) - JSONObject::markStringifiers(m_globalData->firstStringifierToMark); + JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark); + markStack.drain(); + markStack.compact(); JAVASCRIPTCORE_GC_MARKED(); size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects; @@ -1332,12 +1323,14 @@ static const char* typeName(JSCell* cell) { if (cell->isString()) return "string"; +#if USE(JSVALUE32) if (cell->isNumber()) return "number"; +#endif if (cell->isGetterSetter()) return "gettersetter"; ASSERT(cell->isObject()); - const ClassInfo* info = static_cast<JSObject*>(cell)->classInfo(); + const ClassInfo* info = cell->classInfo(); return info ? info->className : "Object"; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h index 852ac59..1a55bb5 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h @@ -39,11 +39,12 @@ namespace JSC { - class MarkedArgumentBuffer; class CollectorBlock; class JSCell; class JSGlobalData; class JSValue; + class MarkedArgumentBuffer; + class MarkStack; enum OperationInProgress { NoOperation, Allocation, Collection }; enum HeapType { PrimaryHeap, NumberHeap }; @@ -100,6 +101,7 @@ namespace JSC { void unprotect(JSValue); static Heap* heap(JSValue); // 0 for immediate values + static Heap* heap(JSCell*); size_t globalObjectCount(); size_t protectedObjectCount(); @@ -111,7 +113,7 @@ namespace JSC { static bool isCellMarked(const JSCell*); static void markCell(JSCell*); - void markConservatively(void* start, void* end); + void markConservatively(MarkStack&, void* start, void* end); HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; } @@ -132,12 +134,17 @@ namespace JSC { Heap(JSGlobalData*); ~Heap(); + template <HeapType heapType> NEVER_INLINE CollectorBlock* allocateBlock(); + template <HeapType heapType> NEVER_INLINE void freeBlock(size_t); + NEVER_INLINE void freeBlock(CollectorBlock*); + void freeBlocks(CollectorHeap*); + void recordExtraCost(size_t); - void markProtectedObjects(); - void markCurrentThreadConservatively(); - void markCurrentThreadConservativelyInternal(); - void markOtherThreadConservatively(Thread*); - void markStackObjectsConservatively(); + void markProtectedObjects(MarkStack&); + void markCurrentThreadConservatively(MarkStack&); + void markCurrentThreadConservativelyInternal(MarkStack&); + void markOtherThreadConservatively(MarkStack&, Thread*); + void markStackObjectsConservatively(MarkStack&); typedef HashCountedSet<JSCell*> ProtectCountSet; @@ -167,9 +174,18 @@ namespace JSC { template<size_t bytesPerWord> struct CellSize; // cell size needs to be a power of two for certain optimizations in collector.cpp - template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; // 32-bit - template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit - const size_t BLOCK_SIZE = 16 * 4096; // 64k +#if USE(JSVALUE32) + template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; +#else + template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 64; }; +#endif + template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; + +#if PLATFORM(WINCE) + const size_t BLOCK_SIZE = 64 * 1024; // 64k +#else + const size_t BLOCK_SIZE = 64 * 4096; // 256k +#endif // derived constants const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h index 7b275bd..abe5038 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h @@ -37,16 +37,26 @@ macro(callee) \ macro(caller) \ macro(compile) \ + macro(configurable) \ macro(constructor) \ + macro(create) \ + macro(defineProperty) \ + macro(defineProperties) \ + macro(enumerable) \ macro(eval) \ macro(exec) \ macro(fromCharCode) \ macro(global) \ + macro(get) \ + macro(getPrototypeOf) \ + macro(getOwnPropertyDescriptor) \ macro(hasOwnProperty) \ macro(ignoreCase) \ macro(index) \ macro(input) \ + macro(isArray) \ macro(isPrototypeOf) \ + macro(keys) \ macro(length) \ macro(message) \ macro(multiline) \ @@ -55,6 +65,7 @@ macro(parse) \ macro(propertyIsEnumerable) \ macro(prototype) \ + macro(set) \ macro(source) \ macro(test) \ macro(toExponential) \ @@ -65,7 +76,9 @@ macro(toPrecision) \ macro(toString) \ macro(UTC) \ + macro(value) \ macro(valueOf) \ + macro(writable) \ macro(displayName) namespace JSC { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp index 04c9a2e..b75a7a5 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp @@ -33,11 +33,6 @@ #ifdef QT_BUILD_SCRIPT_LIB #include "DebuggerCallFrame.h" -#include "SourcePoolQt.h" -#endif - -#if !PLATFORM(WIN_OS) -#include <unistd.h> #endif namespace JSC { @@ -46,33 +41,27 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source) { JSLock lock(exec); - int errLine; - UString errMsg; + ProgramExecutable program(source); + JSObject* error = program.checkSyntax(exec); + if (error) + return Completion(Throw, error); - RefPtr<ProgramNode> progNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - if (!progNode) - return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url())); return Completion(Normal); } Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue) { JSLock lock(exec); - - intptr_t sourceId = source.provider()->asID(); - int errLine; - UString errMsg; - RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - if (!programNode) { - JSValue error = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, source.provider()->url()); + ProgramExecutable program(source); + JSObject* error = program.compile(exec, scopeChain.node()); + if (error) return Completion(Throw, error); - } JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec); JSValue exception; - JSValue result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception); + JSValue result = exec->interpreter()->execute(&program, exec, scopeChain.node(), thisObj, &exception); if (exception) { if (exception.isObject() && asObject(exception)->isWatchdogException()) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h index 477399c..1dcfb00 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h @@ -33,7 +33,7 @@ namespace JSC { class ArgList; class ExecState; - class FunctionBodyNode; + class FunctionExecutable; class JSObject; class JSValue; class ScopeChainNode; @@ -84,7 +84,7 @@ namespace JSC { #endif } native; struct { - FunctionBodyNode* functionBody; + FunctionExecutable* functionExecutable; ScopeChainNode* scopeChain; } js; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp index 6d7d934..1879c3f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp @@ -36,7 +36,7 @@ #include <wtf/MathExtras.h> #if PLATFORM(WINCE) && !PLATFORM(QT) -extern "C" time_t time(time_t* timer); //provided by libce +extern "C" time_t time(time_t* timer); // Provided by libce. #endif #if HAVE(SYS_TIME_H) @@ -51,8 +51,6 @@ using namespace WTF; namespace JSC { -// TODO: MakeTime (15.9.11.1) etc. ? - ASSERT_CLASS_FITS_IN_CELL(DateConstructor); static JSValue JSC_HOST_CALL dateParse(ExecState*, JSObject*, JSValue, const ArgList&); @@ -81,7 +79,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args) if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = getCurrentUTCTime(); else if (numArgs == 1) { - if (args.at(0).isObject(&DateInstance::info)) + if (args.at(0).inherits(&DateInstance::info)) value = asDateInstance(args.at(0))->internalNumber(); else { JSValue primitive = args.at(0).toPrimitive(exec); @@ -100,17 +98,17 @@ JSObject* constructDate(ExecState* exec, const ArgList& args) || (numArgs >= 7 && isnan(args.at(6).toNumber(exec)))) value = NaN; else { - GregorianDateTime t; - int year = args.at(0).toInt32(exec); - t.year = (year >= 0 && year <= 99) ? year : year - 1900; - t.month = args.at(1).toInt32(exec); - t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1; - t.hour = args.at(3).toInt32(exec); - t.minute = args.at(4).toInt32(exec); - t.second = args.at(5).toInt32(exec); - t.isDST = -1; - double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0; - value = gregorianDateTimeToMS(t, ms, false); + GregorianDateTime t; + int year = args.at(0).toInt32(exec); + t.year = (year >= 0 && year <= 99) ? year : year - 1900; + t.month = args.at(1).toInt32(exec); + t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1; + t.hour = args.at(3).toInt32(exec); + t.minute = args.at(4).toInt32(exec); + t.second = args.at(5).toInt32(exec); + t.isDST = -1; + double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0; + value = gregorianDateTimeToMS(t, ms, false); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp index e2482f4..c6f7dec 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp @@ -198,8 +198,8 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L { #if HAVE(LANGINFO_H) static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT }; -#elif PLATFORM(WINCE) && !PLATFORM(QT) - // strftime() we are using does not support # +#elif (PLATFORM(WINCE) && !PLATFORM(QT)) || PLATFORM(SYMBIAN) + // strftime() does not support '#' on WinCE or Symbian static const char* const formatStrings[] = { "%c", "%x", "%X" }; #else static const char* const formatStrings[] = { "%#c", "%#x", "%X" }; @@ -407,11 +407,17 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, slot); } + +bool DatePrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticFunctionDescriptor<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, descriptor); +} + // Functions JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -428,7 +434,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -445,7 +451,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -457,17 +463,17 @@ JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSVal GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); - // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) - // 6 for formatting and one for null termination = 23. We add one extra character to allow us to force null termination. - char buffer[24]; - snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second); + // 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))); buffer[sizeof(buffer) - 1] = 0; return jsNontrivialString(exec, buffer); } JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -484,7 +490,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -501,7 +507,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -514,7 +520,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JS JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -527,7 +533,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -540,7 +546,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -553,7 +559,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue t JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -570,7 +576,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSVal JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -587,7 +593,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JS JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -604,7 +610,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -621,7 +627,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -638,7 +644,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSVal JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -655,7 +661,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue t JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -672,7 +678,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValu JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -689,7 +695,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue th JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -706,7 +712,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -723,7 +729,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -740,7 +746,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSVal JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -757,7 +763,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValu JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -774,7 +780,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSV JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -791,7 +797,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValu JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; @@ -808,7 +814,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSV JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -823,7 +829,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, J JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -838,7 +844,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -855,7 +861,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -868,7 +874,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue t static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -899,7 +905,7 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); @@ -1020,7 +1026,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JS JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; @@ -1062,7 +1068,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&DateInstance::info)) + if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h index 5f4d0ec..12fabda 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h @@ -32,13 +32,14 @@ namespace JSC { DatePrototype(ExecState*, PassRefPtr<Structure>); virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); } }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp index 1aa9034..c094b75 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp @@ -97,6 +97,12 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const char* message) return create(exec, type, message, -1, -1, NULL); } +JSObject* throwError(ExecState* exec, JSObject* error) +{ + exec->setException(error); + return error; +} + JSObject* throwError(ExecState* exec, ErrorType type) { JSObject* error = Error::create(exec, type, UString(), -1, -1, NULL); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h index fb864ee..d84b81b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h @@ -59,6 +59,7 @@ namespace JSC { JSObject* throwError(ExecState*, ErrorType, const UString& message); JSObject* throwError(ExecState*, ErrorType, const char* message); JSObject* throwError(ExecState*, ErrorType); + JSObject* throwError(ExecState*, JSObject*); #ifdef QT_BUILD_SCRIPT_LIB # define JSC_ERROR_FILENAME_PROPERTYNAME "fileName" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp index e63594c..cc18b95 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -74,7 +74,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString message = "Can't find variable: "; message.append(ident.ustring()); - JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); @@ -136,7 +136,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message); - JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); @@ -157,7 +157,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned by startPoint++; UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor"); - JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); @@ -171,7 +171,7 @@ JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecod int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function"); - JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); @@ -201,7 +201,7 @@ JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object"); - JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()); + JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h index 09d99dc..4c5bec1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h @@ -29,20 +29,19 @@ #ifndef ExceptionHelpers_h #define ExceptionHelpers_h -#include "JSImmediate.h" namespace JSC { class CodeBlock; class ExecState; class Identifier; - class Instruction; class JSGlobalData; class JSNotAnObjectErrorStub; class JSObject; class JSValue; class Node; - + struct Instruction; + JSValue createInterruptedExecutionException(JSGlobalData*); JSValue createStackOverflowError(ExecState*); JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp new file mode 100644 index 0000000..5e79794 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp @@ -0,0 +1,280 @@ +/* + * 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. + */ + +#include "config.h" +#include "Executable.h" + +#include "BytecodeGenerator.h" +#include "CodeBlock.h" +#include "JIT.h" +#include "Parser.h" +#include "Vector.h" + +namespace JSC { + +#if ENABLE(JIT) +NativeExecutable::~NativeExecutable() +{ +} +#endif + +VPtrHackExecutable::~VPtrHackExecutable() +{ +} + +EvalExecutable::~EvalExecutable() +{ + delete m_evalCodeBlock; +} + +ProgramExecutable::~ProgramExecutable() +{ + delete m_programCodeBlock; +} + +FunctionExecutable::~FunctionExecutable() +{ + delete m_codeBlock; +} + +JSObject* EvalExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + int errLine; + UString errMsg; + RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg); + if (!evalNode) + return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url()); + recordParse(evalNode->features(), evalNode->lineNo(), evalNode->lastLine()); + + ScopeChain scopeChain(scopeChainNode); + JSGlobalObject* globalObject = scopeChain.globalObject(); + + ASSERT(!m_evalCodeBlock); + m_evalCodeBlock = new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()); + OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock)); + generator->generate(); + + evalNode->destroyData(); + return 0; +} + +JSObject* ProgramExecutable::checkSyntax(ExecState* exec) +{ + int errLine; + UString errMsg; + RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg); + if (!programNode) + return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url()); + return 0; +} + +JSObject* ProgramExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + int errLine; + UString errMsg; + RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg); + if (!programNode) + return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url()); + recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine()); + + ScopeChain scopeChain(scopeChainNode); + JSGlobalObject* globalObject = scopeChain.globalObject(); + + ASSERT(!m_programCodeBlock); + m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()); + OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock)); + generator->generate(); + + programNode->destroyData(); + return 0; +} + +void FunctionExecutable::compile(ExecState*, ScopeChainNode* scopeChainNode) +{ + JSGlobalData* globalData = scopeChainNode->globalData; + RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source); + if (m_forceUsesArguments) + body->setUsesArguments(); + body->finishParsing(m_parameters, m_name); + recordParse(body->features(), body->lineNo(), body->lastLine()); + + ScopeChain scopeChain(scopeChainNode); + JSGlobalObject* globalObject = scopeChain.globalObject(); + + ASSERT(!m_codeBlock); + m_codeBlock = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset()); + OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlock->symbolTable(), m_codeBlock)); + generator->generate(); + m_numParameters = m_codeBlock->m_numParameters; + ASSERT(m_numParameters); + m_numVariables = m_codeBlock->m_numVars; + + body->destroyData(); +} + +#if ENABLE(JIT) + +void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + CodeBlock* codeBlock = &bytecode(exec, scopeChainNode); + m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock); + +#if !ENABLE(OPCODE_SAMPLING) + if (!BytecodeGenerator::dumpsGeneratedCode()) + codeBlock->discardBytecode(); +#endif +} + +void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + CodeBlock* codeBlock = &bytecode(exec, scopeChainNode); + m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock); + +#if !ENABLE(OPCODE_SAMPLING) + if (!BytecodeGenerator::dumpsGeneratedCode()) + codeBlock->discardBytecode(); +#endif +} + +void FunctionExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + CodeBlock* codeBlock = &bytecode(exec, scopeChainNode); + m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock); + +#if !ENABLE(OPCODE_SAMPLING) + if (!BytecodeGenerator::dumpsGeneratedCode()) + codeBlock->discardBytecode(); +#endif +} + +#endif + +void FunctionExecutable::markAggregate(MarkStack& markStack) +{ + if (m_codeBlock) + m_codeBlock->markAggregate(markStack); +} + +ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) +{ + RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source); + if (m_forceUsesArguments) + newFunctionBody->setUsesArguments(); + newFunctionBody->finishParsing(m_parameters, m_name); + + ScopeChain scopeChain(scopeChainNode); + JSGlobalObject* globalObject = scopeChain.globalObject(); + + OwnPtr<CodeBlock> newCodeBlock(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset())); + globalData->functionCodeBlockBeingReparsed = newCodeBlock.get(); + + OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get())); + generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock)); + generator->generate(); + + ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount()); + +#if ENABLE(JIT) + JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get()); + ASSERT(newJITCode.size() == generatedJITCode().size()); +#endif + + globalData->functionCodeBlockBeingReparsed = 0; + + return newCodeBlock->extractExceptionInfo(); +} + +ExceptionInfo* EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) +{ + RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, m_source); + + ScopeChain scopeChain(scopeChainNode); + JSGlobalObject* globalObject = scopeChain.globalObject(); + + OwnPtr<EvalCodeBlock> newCodeBlock(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); + + OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newEvalBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get())); + generator->setRegeneratingForExceptionInfo(static_cast<EvalCodeBlock*>(codeBlock)); + generator->generate(); + + ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount()); + +#if ENABLE(JIT) + JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get()); + ASSERT(newJITCode.size() == generatedJITCode().size()); +#endif + + return newCodeBlock->extractExceptionInfo(); +} + +void FunctionExecutable::recompile(ExecState*) +{ + delete m_codeBlock; + m_codeBlock = 0; + m_numParameters = NUM_PARAMETERS_NOT_COMPILED; +#if ENABLE(JIT) + m_jitCode = JITCode(); +#endif +} + +PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg) +{ + RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg); + if (!program) + return 0; + + StatementNode* exprStatement = program->singleStatement(); + ASSERT(exprStatement); + ASSERT(exprStatement->isExprStatement()); + if (!exprStatement || !exprStatement->isExprStatement()) + return 0; + + ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); + ASSERT(funcExpr); + ASSERT(funcExpr->isFuncExprNode()); + if (!funcExpr || !funcExpr->isFuncExprNode()) + return 0; + + FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); + ASSERT(body); + return FunctionExecutable::create(functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); +} + +UString FunctionExecutable::paramString() const +{ + FunctionParameters& parameters = *m_parameters; + UString s(""); + for (size_t pos = 0; pos < parameters.size(); ++pos) { + if (!s.isEmpty()) + s += ", "; + s += parameters[pos].ustring(); + } + + return s; +} + +}; + + diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h new file mode 100644 index 0000000..f3003dd --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h @@ -0,0 +1,315 @@ +/* + * 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 Executable_h +#define Executable_h + +#include "JSFunction.h" +#include "Nodes.h" + +namespace JSC { + + class CodeBlock; + class Debugger; + class EvalCodeBlock; + class ProgramCodeBlock; + class ScopeChainNode; + + struct ExceptionInfo; + + class ExecutableBase : public RefCounted<ExecutableBase> { + friend class JIT; + + protected: + static const int NUM_PARAMETERS_IS_HOST = 0; + static const int NUM_PARAMETERS_NOT_COMPILED = -1; + + public: + ExecutableBase(int numParameters) + : m_numParameters(numParameters) + { + } + + virtual ~ExecutableBase() {} + + bool isHostFunction() const { return m_numParameters == NUM_PARAMETERS_IS_HOST; } + + protected: + int m_numParameters; + +#if ENABLE(JIT) + public: + JITCode& generatedJITCode() + { + ASSERT(m_jitCode); + return m_jitCode; + } + + ExecutablePool* getExecutablePool() + { + return m_jitCode.getExecutablePool(); + } + + protected: + JITCode m_jitCode; +#endif + }; + +#if ENABLE(JIT) + class NativeExecutable : public ExecutableBase { + public: + NativeExecutable(ExecState* exec) + : ExecutableBase(NUM_PARAMETERS_IS_HOST) + { + m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk())); + } + + ~NativeExecutable(); + }; +#endif + + class VPtrHackExecutable : public ExecutableBase { + public: + VPtrHackExecutable() + : ExecutableBase(NUM_PARAMETERS_IS_HOST) + { + } + + ~VPtrHackExecutable(); + }; + + class ScriptExecutable : public ExecutableBase { + public: + ScriptExecutable(const SourceCode& source) + : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) + , m_source(source) + , m_features(0) + { + } + + const SourceCode& source() { return m_source; } + intptr_t sourceID() const { return m_source.provider()->asID(); } + const UString& sourceURL() const { return m_source.provider()->url(); } + int lineNo() const { return m_firstLine; } + int lastLine() const { return m_lastLine; } + + bool usesEval() const { return m_features & EvalFeature; } + bool usesArguments() const { return m_features & ArgumentsFeature; } + bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); } + + virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0; + + protected: + void recordParse(CodeFeatures features, int firstLine, int lastLine) + { + m_features = features; + m_firstLine = firstLine; + m_lastLine = lastLine; + } + + SourceCode m_source; + CodeFeatures m_features; + int m_firstLine; + int m_lastLine; + }; + + class EvalExecutable : public ScriptExecutable { + public: + EvalExecutable(const SourceCode& source) + : ScriptExecutable(source) + , m_evalCodeBlock(0) + { + } + + ~EvalExecutable(); + + EvalCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + if (!m_evalCodeBlock) { + JSObject* error = compile(exec, scopeChainNode); + ASSERT_UNUSED(!error, error); + } + return *m_evalCodeBlock; + } + + JSObject* compile(ExecState*, ScopeChainNode*); + + ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*); + static PassRefPtr<EvalExecutable> create(const SourceCode& source) { return adoptRef(new EvalExecutable(source)); } + + private: + EvalCodeBlock* m_evalCodeBlock; + +#if ENABLE(JIT) + public: + JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + if (!m_jitCode) + generateJITCode(exec, scopeChainNode); + return m_jitCode; + } + + private: + void generateJITCode(ExecState*, ScopeChainNode*); +#endif + }; + + class ProgramExecutable : public ScriptExecutable { + public: + ProgramExecutable(const SourceCode& source) + : ScriptExecutable(source) + , m_programCodeBlock(0) + { + } + + ~ProgramExecutable(); + + ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + if (!m_programCodeBlock) { + JSObject* error = compile(exec, scopeChainNode); + ASSERT_UNUSED(!error, error); + } + return *m_programCodeBlock; + } + + JSObject* checkSyntax(ExecState*); + JSObject* compile(ExecState*, ScopeChainNode*); + + // CodeBlocks for program code are transient and therefore do not gain from from throwing out there exception information. + ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; } + + private: + ProgramCodeBlock* m_programCodeBlock; + +#if ENABLE(JIT) + public: + JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + if (!m_jitCode) + generateJITCode(exec, scopeChainNode); + return m_jitCode; + } + + private: + void generateJITCode(ExecState*, ScopeChainNode*); +#endif + }; + + class FunctionExecutable : public ScriptExecutable { + friend class JIT; + public: + static PassRefPtr<FunctionExecutable> create(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + { + return adoptRef(new FunctionExecutable(name, source, forceUsesArguments, parameters, firstLine, lastLine)); + } + + ~FunctionExecutable(); + + JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain) + { + return new (exec) JSFunction(exec, this, scopeChain); + } + + CodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + ASSERT(scopeChainNode); + if (!m_codeBlock) + compile(exec, scopeChainNode); + return *m_codeBlock; + } + + bool isGenerated() const + { + return m_codeBlock; + } + + CodeBlock& generatedBytecode() + { + ASSERT(m_codeBlock); + return *m_codeBlock; + } + + const Identifier& name() { return m_name; } + size_t parameterCount() const { return m_parameters->size(); } + size_t variableCount() const { return m_numVariables; } + UString paramString() const; + UString parameterName(int i) const { return (*m_parameters)[i].ustring(); } + + void recompile(ExecState*); + ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*); + void markAggregate(MarkStack& markStack); + static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); + + private: + FunctionExecutable(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + : ScriptExecutable(source) + , m_forceUsesArguments(forceUsesArguments) + , m_parameters(parameters) + , m_codeBlock(0) + , m_name(name) + , m_numVariables(0) + { + m_firstLine = firstLine; + m_lastLine = lastLine; + } + + void compile(ExecState*, ScopeChainNode*); + + bool m_forceUsesArguments; + RefPtr<FunctionParameters> m_parameters; + CodeBlock* m_codeBlock; + Identifier m_name; + size_t m_numVariables; + +#if ENABLE(JIT) + public: + JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode) + { + if (!m_jitCode) + generateJITCode(exec, scopeChainNode); + return m_jitCode; + } + + private: + void generateJITCode(ExecState*, ScopeChainNode*); +#endif + }; + + inline FunctionExecutable* JSFunction::jsExecutable() const + { + ASSERT(!isHostFunctionNonInline()); + return static_cast<FunctionExecutable*>(m_executable.get()); + } + + inline bool JSFunction::isHostFunction() const + { + ASSERT(m_executable); + return m_executable->isHostFunction(); + } + +} + +#endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp index f4f5cc8..d5eb20f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp @@ -66,32 +66,6 @@ CallType FunctionConstructor::getCallData(CallData& callData) return CallTypeHost; } -FunctionBodyNode* extractFunctionBody(ProgramNode* program) -{ - if (!program) - return 0; - - StatementVector& children = program->children(); - if (children.size() != 1) - return 0; - - StatementNode* exprStatement = children[0]; - ASSERT(exprStatement); - ASSERT(exprStatement->isExprStatement()); - if (!exprStatement || !exprStatement->isExprStatement()) - return 0; - - ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); - ASSERT(funcExpr); - ASSERT(funcExpr->isFuncExprNode()); - if (!funcExpr || !funcExpr->isFuncExprNode()) - return 0; - - FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); - ASSERT(body); - return body; -} - // ECMA 15.3.2 The Function Constructor JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) { @@ -113,15 +87,13 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi int errLine; UString errMsg; SourceCode source = makeSource(program, sourceURL, lineNumber); - RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - - FunctionBodyNode* body = extractFunctionBody(programNode.get()); - if (!body) + RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); + if (!function) return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue()); - return new (exec) JSFunction(exec, functionName, body, scopeChain.node()); + return new (exec) JSFunction(exec, function, scopeChain.node()); } // ECMA 15.3.2 The Function Constructor diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h index 124b354..e8486dc 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h @@ -26,8 +26,6 @@ namespace JSC { class FunctionPrototype; - class ProgramNode; - class FunctionBodyNode; class FunctionConstructor : public InternalFunction { public: @@ -41,8 +39,6 @@ namespace JSC { JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber); JSObject* constructFunction(ExecState*, const ArgList&); - FunctionBodyNode* extractFunctionBody(ProgramNode*); - } // namespace JSC #endif // FunctionConstructor_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp index ff8e57b..1df998d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -84,16 +84,17 @@ static inline void insertSemicolonIfNeeded(UString& functionBody) JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (thisValue.isObject(&JSFunction::info)) { + if (thisValue.inherits(&JSFunction::info)) { JSFunction* function = asFunction(thisValue); if (!function->isHostFunction()) { - UString functionBody = function->body()->toSourceString(); - insertSemicolonIfNeeded(functionBody); - return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + functionBody); + FunctionExecutable* executable = function->jsExecutable(); + UString sourceString = executable->source().toString(); + insertSemicolonIfNeeded(sourceString); + return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + executable->paramString() + ") " + sourceString); } } - if (thisValue.isObject(&InternalFunction::info)) { + if (thisValue.inherits(&InternalFunction::info)) { InternalFunction* function = asInternalFunction(thisValue); return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}"); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h index 607ddab..469191e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot)); + return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp index cd1b40a..7e54053 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,52 +28,14 @@ namespace JSC { -void GetterSetter::mark() +void GetterSetter::markChildren(MarkStack& markStack) { - JSCell::mark(); + JSCell::markChildren(markStack); - if (m_getter && !m_getter->marked()) - m_getter->mark(); - if (m_setter && !m_setter->marked()) - m_setter->mark(); -} - -JSValue GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const -{ - ASSERT_NOT_REACHED(); - return jsNull(); -} - -bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue& value) -{ - ASSERT_NOT_REACHED(); - number = 0; - value = JSValue(); - return true; -} - -bool GetterSetter::toBoolean(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return false; -} - -double GetterSetter::toNumber(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return 0.0; -} - -UString GetterSetter::toString(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return UString::null(); -} - -JSObject* GetterSetter::toObject(ExecState* exec) const -{ - ASSERT_NOT_REACHED(); - return jsNull().toObject(exec); + if (m_getter) + markStack.append(m_getter); + if (m_setter) + markStack.append(m_setter); } bool GetterSetter::isGetterSetter() const diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h index e6b74a1..73dd854 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,6 +25,8 @@ #include "JSCell.h" +#include "CallFrame.h" + namespace JSC { class JSObject; @@ -33,30 +35,26 @@ namespace JSC { // for a property. class GetterSetter : public JSCell { public: - GetterSetter() - : JSCell(0) + GetterSetter(ExecState* exec) + : JSCell(exec->globalData().getterSetterStructure.get()) , m_getter(0) , m_setter(0) { } - virtual void mark(); + virtual void markChildren(MarkStack&); JSObject* getter() const { return m_getter; } void setGetter(JSObject* getter) { m_getter = getter; } JSObject* setter() const { return m_setter; } void setSetter(JSObject* setter) { m_setter = setter; } - + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(GetterSetterType)); + } private: virtual bool isGetterSetter() const; - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - JSObject* m_getter; JSObject* m_setter; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp index b0d4c25..3074f95 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * @@ -39,11 +39,10 @@ GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<Structure> st ASSERT_ARG(cachedGlobalObject, cachedGlobalObject); } -void GlobalEvalFunction::mark() +void GlobalEvalFunction::markChildren(MarkStack& markStack) { - PrototypeFunction::mark(); - if (!m_cachedGlobalObject->marked()) - m_cachedGlobalObject->mark(); + PrototypeFunction::markChildren(markStack); + markStack.append(m_cachedGlobalObject); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h index 49b1847..c56b0dc 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * @@ -35,8 +35,13 @@ namespace JSC { GlobalEvalFunction(ExecState*, PassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject); JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; } + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + } + private: - virtual void mark(); + virtual void markChildren(MarkStack&); JSGlobalObject* m_cachedGlobalObject; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h index 631cf42..2249179 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h @@ -54,6 +54,8 @@ namespace JSC { const char* ascii() const { return _ustring.ascii(); } static Identifier from(ExecState* exec, unsigned y) { return Identifier(exec, UString::from(y)); } + static Identifier from(ExecState* exec, int y) { return Identifier(exec, UString::from(y)); } + static Identifier from(ExecState* exec, double y) { return Identifier(exec, UString::from(y)); } bool isNull() const { return _ustring.isNull(); } bool isEmpty() const { return _ustring.isEmpty(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp index a0620e7..fea89f8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp @@ -29,7 +29,6 @@ #include "config.h" #include "InitializeThreading.h" -#include "JSImmediate.h" #include "Collector.h" #include "dtoa.h" #include "Identifier.h" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h index 310644c..37077f6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h @@ -42,7 +42,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark)); } protected: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.cpp new file mode 100644 index 0000000..e83724a --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "JSAPIValueWrapper.h" + +#include "NumberObject.h" +#include "UString.h" + +namespace JSC { + +} // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h new file mode 100644 index 0000000..88a8493 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef JSAPIValueWrapper_h +#define JSAPIValueWrapper_h + +#include <wtf/Platform.h> + +#include "JSCell.h" +#include "CallFrame.h" + +namespace JSC { + + class JSAPIValueWrapper : public JSCell { + friend JSValue jsAPIValueWrapper(ExecState*, JSValue); + public: + JSValue value() const { return m_value; } + + virtual bool isAPIValueWrapper() const { return true; } + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(CompoundType)); + } + + + private: + JSAPIValueWrapper(ExecState* exec, JSValue value) + : JSCell(exec->globalData().apiWrapperStructure.get()) + , m_value(value) + { + ASSERT(!value.isCell()); + } + + JSValue m_value; + }; + + inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value) + { + return new (exec) JSAPIValueWrapper(exec, value); + } + +} // namespace JSC + +#endif // JSAPIValueWrapper_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp index 184a9cb..d989a89 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -39,8 +39,8 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation); const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 }; -JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody) - : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame->registers())) +JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionExecutable> functionExecutable) + : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers())) { } @@ -49,35 +49,23 @@ JSActivation::~JSActivation() delete d(); } -void JSActivation::mark() +void JSActivation::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); Register* registerArray = d()->registerArray.get(); if (!registerArray) return; - size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1; + size_t numParametersMinusThis = d()->functionExecutable->parameterCount(); - size_t i = 0; - size_t count = numParametersMinusThis; - for ( ; i < count; ++i) { - Register& r = registerArray[i]; - if (!r.marked()) - r.mark(); - } + size_t count = numParametersMinusThis; + markStack.appendValues(registerArray, count); - size_t numVars = d()->functionBody->generatedBytecode().m_numVars; + size_t numVars = d()->functionExecutable->variableCount(); // Skip the call frame, which sits between the parameters and vars. - i += RegisterFile::CallFrameHeaderSize; - count += RegisterFile::CallFrameHeaderSize + numVars; - - for ( ; i < count; ++i) { - Register& r = registerArray[i]; - if (r.jsValue() && !r.marked()) - r.mark(); - } + markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues); } bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -148,14 +136,14 @@ JSObject* JSActivation::toThisObject(ExecState* exec) const bool JSActivation::isDynamicScope() const { - return d()->functionBody->usesEval(); + return d()->functionExecutable->usesEval(); } JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSActivation* activation = asActivation(slot.slotBase()); - if (activation->d()->functionBody->usesArguments()) { + if (activation->d()->functionExecutable->usesArguments()) { PropertySlot slot; activation->symbolTableGet(exec->propertyNames().arguments, slot); return slot.getValue(exec, exec->propertyNames().arguments); @@ -168,7 +156,7 @@ JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const arguments->copyRegisters(); callFrame->setCalleeArguments(arguments); } - ASSERT(arguments->isObject(&Arguments::info)); + ASSERT(arguments->inherits(&Arguments::info)); return arguments; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h index b48ef25..90815a1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -43,10 +43,10 @@ namespace JSC { class JSActivation : public JSVariableObject { typedef JSVariableObject Base; public: - JSActivation(CallFrame*, PassRefPtr<FunctionBodyNode>); + JSActivation(CallFrame*, PassRefPtr<FunctionExecutable>); virtual ~JSActivation(); - virtual void mark(); + virtual void markChildren(MarkStack&); virtual bool isDynamicScope() const; @@ -70,13 +70,20 @@ namespace JSC { private: struct JSActivationData : public JSVariableObjectData { - JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers) - : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers) - , functionBody(functionBody) + JSActivationData(PassRefPtr<FunctionExecutable> _functionExecutable, Register* registers) + : JSVariableObjectData(_functionExecutable->generatedBytecode().symbolTable(), registers) + , functionExecutable(_functionExecutable) { + // We have to manually ref and deref the symbol table as JSVariableObjectData + // doesn't know about SharedSymbolTable + functionExecutable->generatedBytecode().sharedSymbolTable()->ref(); + } + ~JSActivationData() + { + static_cast<SharedSymbolTable*>(symbolTable)->deref(); } - RefPtr<FunctionBodyNode> functionBody; + RefPtr<FunctionExecutable> functionExecutable; }; static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp index a8207e3..1a4402c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2003 Peter Kelly (pmk@post.com) * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) * @@ -25,6 +25,8 @@ #include "ArrayPrototype.h" #include "CachedCall.h" +#include "Error.h" +#include "Executable.h" #include "PropertyNameArray.h" #include <wtf/AVLTree.h> #include <wtf/Assertions.h> @@ -134,9 +136,9 @@ JSArray::JSArray(PassRefPtr<Structure> structure) unsigned initialCapacity = 0; m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_fastAccessCutoff = 0; m_storage->m_vectorLength = initialCapacity; - m_storage->m_length = 0; + + m_fastAccessCutoff = 0; checkConsistency(); } @@ -146,40 +148,45 @@ JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength) { unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX); - m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_fastAccessCutoff = 0; - m_storage->m_vectorLength = initialCapacity; + m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialLength; + m_storage->m_vectorLength = initialCapacity; + m_storage->m_numValuesInVector = 0; + m_storage->m_sparseValueMap = 0; + m_storage->lazyCreationData = 0; - Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); + JSValue* vector = m_storage->m_vector; + for (size_t i = 0; i < initialCapacity; ++i) + vector[i] = JSValue(); + + m_fastAccessCutoff = 0; checkConsistency(); + + Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); } JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list) : JSObject(structure) { - unsigned length = list.size(); + unsigned initialCapacity = list.size(); - m_fastAccessCutoff = length; - - ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length))); - - storage->m_vectorLength = length; - storage->m_numValuesInVector = length; - storage->m_sparseValueMap = 0; - storage->m_length = length; + m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); + m_storage->m_length = initialCapacity; + m_storage->m_vectorLength = initialCapacity; + m_storage->m_numValuesInVector = initialCapacity; + m_storage->m_sparseValueMap = 0; size_t i = 0; ArgList::const_iterator end = list.end(); for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) - storage->m_vector[i] = *it; + m_storage->m_vector[i] = *it; - m_storage = storage; - - Heap::heap(this)->reportExtraMemoryCost(storageSize(length)); + m_fastAccessCutoff = initialCapacity; checkConsistency(); + + Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); } JSArray::~JSArray() @@ -216,7 +223,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot } } - return false; + return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, i), slot); } bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -234,6 +241,37 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName return JSObject::getOwnPropertySlot(exec, propertyName, slot); } +bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + if (propertyName == exec->propertyNames().length) { + descriptor.setDescriptor(jsNumber(exec, length()), DontDelete | DontEnum); + return true; + } + + bool isArrayIndex; + unsigned i = propertyName.toArrayIndex(&isArrayIndex); + if (isArrayIndex) { + if (i >= m_storage->m_length) + return false; + if (i < m_storage->m_vectorLength) { + JSValue value = m_storage->m_vector[i]; + if (value) { + descriptor.setDescriptor(value, 0); + return true; + } + } else if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { + if (i >= MIN_SPARSE_ARRAY_INDEX) { + SparseArrayValueMap::iterator it = map->find(i); + if (it != map->end()) { + descriptor.setDescriptor(it->second, 0); + return true; + } + } + } + } + return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + // ECMA 15.4.5.1 void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { @@ -343,8 +381,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu } } - storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength))); - if (!storage) { + if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) { throwOutOfMemoryError(exec); return; } @@ -427,7 +464,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete) return false; } -void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { // FIXME: Filling PropertyNameArray with an identifier for every integer // is incredibly inefficient for large arrays. We need a different approach, @@ -447,7 +484,7 @@ void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames propertyNames.add(Identifier::from(exec, it->first)); } - JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } bool JSArray::increaseVectorLength(unsigned newLength) @@ -462,8 +499,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); unsigned newVectorLength = increasedVectorLength(newLength); - storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength))); - if (!storage) + if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) return false; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); @@ -596,27 +632,9 @@ void JSArray::push(ExecState* exec, JSValue value) putSlowCase(exec, m_storage->m_length++, value); } -void JSArray::mark() +void JSArray::markChildren(MarkStack& markStack) { - JSObject::mark(); - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength); - for (unsigned i = 0; i < usedVectorLength; ++i) { - JSValue value = storage->m_vector[i]; - if (value && !value.marked()) - value.mark(); - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { - JSValue value = it->second; - if (!value.marked()) - value.mark(); - } - } + markChildrenDirect(markStack); } static int compareNumbersForQSort(const void* a, const void* b) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h index 73e1711..37ed72b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +38,7 @@ namespace JSC { class JSArray : public JSObject { friend class JIT; + friend class Walker; public: explicit JSArray(PassRefPtr<Structure>); @@ -47,6 +48,7 @@ namespace JSC { virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem. static JS_EXPORTDATA const ClassInfo info; @@ -82,13 +84,15 @@ namespace JSC { { return Structure::create(prototype, TypeInfo(ObjectType)); } + + inline void markChildrenDirect(MarkStack& markStack); protected: virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); - virtual void mark(); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); + virtual void markChildren(MarkStack&); void* lazyCreationData(); void setLazyCreationData(void*); @@ -117,14 +121,104 @@ namespace JSC { JSArray* constructArray(ExecState*, JSValue singleItemValue); JSArray* constructArray(ExecState*, const ArgList& values); + inline JSArray* asArray(JSCell* cell) + { + ASSERT(cell->inherits(&JSArray::info)); + return static_cast<JSArray*>(cell); + } + inline JSArray* asArray(JSValue value) { - ASSERT(asObject(value)->inherits(&JSArray::info)); - return static_cast<JSArray*>(asObject(value)); + return asArray(value.asCell()); } - inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; } + inline bool isJSArray(JSGlobalData* globalData, JSValue v) + { + return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; + } + inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; } + inline void JSArray::markChildrenDirect(MarkStack& markStack) + { + JSObject::markChildrenDirect(markStack); + + ArrayStorage* storage = m_storage; + + unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); + markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); + + if (SparseArrayValueMap* map = storage->m_sparseValueMap) { + SparseArrayValueMap::iterator end = map->end(); + for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) + markStack.append(it->second); + } + } + + inline void MarkStack::markChildren(JSCell* cell) + { + ASSERT(Heap::isCellMarked(cell)); + if (cell->structure()->typeInfo().hasDefaultMark()) { +#ifdef NDEBUG + asObject(cell)->markChildrenDirect(*this); +#else + ASSERT(!m_isCheckingForDefaultMarkViolation); + m_isCheckingForDefaultMarkViolation = true; + cell->markChildren(*this); + ASSERT(m_isCheckingForDefaultMarkViolation); + m_isCheckingForDefaultMarkViolation = false; +#endif + return; + } + if (cell->vptr() == m_jsArrayVPtr) { + asArray(cell)->markChildrenDirect(*this); + return; + } + cell->markChildren(*this); + } + + inline void MarkStack::drain() + { + while (!m_markSets.isEmpty() || !m_values.isEmpty()) { + while (!m_markSets.isEmpty() && m_values.size() < 50) { + ASSERT(!m_markSets.isEmpty()); + MarkSet& current = m_markSets.last(); + ASSERT(current.m_values); + JSValue* end = current.m_end; + ASSERT(current.m_values); + ASSERT(current.m_values != end); + findNextUnmarkedNullValue: + ASSERT(current.m_values != end); + JSValue value = *current.m_values; + current.m_values++; + + JSCell* cell; + if (!value || !value.isCell() || Heap::isCellMarked(cell = value.asCell())) { + if (current.m_values == end) { + m_markSets.removeLast(); + continue; + } + goto findNextUnmarkedNullValue; + } + + Heap::markCell(cell); + if (cell->structure()->typeInfo().type() < CompoundType) { + if (current.m_values == end) { + m_markSets.removeLast(); + continue; + } + goto findNextUnmarkedNullValue; + } + + if (current.m_values == end) + m_markSets.removeLast(); + + markChildren(cell); + } + while (!m_values.isEmpty()) + markChildren(m_values.removeLast()); + } + } + } // namespace JSC #endif // JSArray_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp index d00b69c..0907099 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp @@ -45,7 +45,7 @@ JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteA PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) { - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType)); + PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark)); return result; } @@ -59,7 +59,18 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& property } return JSObject::getOwnPropertySlot(exec, propertyName, slot); } - + +bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + bool ok; + unsigned index = propertyName.toUInt32(&ok, false); + if (ok && canAccessIndex(index)) { + descriptor.setDescriptor(getIndex(exec, index), DontDelete); + return true; + } + return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { if (canAccessIndex(propertyName)) { @@ -85,12 +96,12 @@ void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value) setIndex(exec, propertyName, value); } -void JSByteArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { unsigned length = m_storage->length(); for (unsigned i = 0; i < length; ++i) propertyNames.add(Identifier::from(exec, i)); - JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h index c43c3ea..5ea0505 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h @@ -33,7 +33,7 @@ namespace JSC { class JSByteArray : public JSObject { - friend class VPtrSet; + friend struct VPtrSet; public: bool canAccessIndex(unsigned i) { return i < m_storage->length(); } JSValue getIndex(ExecState* exec, unsigned i) @@ -78,10 +78,11 @@ namespace JSC { virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue); - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, bool includeNonEnumerable = false); virtual const ClassInfo* classInfo() const { return m_classInfo; } static const ClassInfo s_defaultInfo; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp index 10a91f7..1cfe72d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp @@ -90,16 +90,6 @@ bool JSCell::getUInt32(uint32_t&) const return false; } -bool JSCell::getTruncatedInt32(int32_t&) const -{ - return false; -} - -bool JSCell::getTruncatedUInt32(uint32_t&) const -{ - return false; -} - bool JSCell::getString(UString&stringValue) const { if (!isString()) @@ -115,7 +105,7 @@ UString JSCell::getString() const JSObject* JSCell::getObject() { - return isObject() ? static_cast<JSObject*>(this) : 0; + return isObject() ? asObject(this) : 0; } const JSObject* JSCell::getObject() const @@ -207,4 +197,40 @@ bool JSCell::isGetterSetter() const return false; } +JSValue JSCell::toPrimitive(ExecState*, PreferredPrimitiveType) const +{ + ASSERT_NOT_REACHED(); + return JSValue(); +} + +bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&) +{ + ASSERT_NOT_REACHED(); + return false; +} + +bool JSCell::toBoolean(ExecState*) const +{ + ASSERT_NOT_REACHED(); + return false; +} + +double JSCell::toNumber(ExecState*) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +UString JSCell::toString(ExecState*) const +{ + ASSERT_NOT_REACHED(); + return UString(); +} + +JSObject* JSCell::toObject(ExecState*) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h index 4743baf..d015b9c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,11 +23,12 @@ #ifndef JSCell_h #define JSCell_h -#include <wtf/Noncopyable.h> -#include "Structure.h" -#include "JSValue.h" -#include "JSImmediate.h" #include "Collector.h" +#include "JSImmediate.h" +#include "JSValue.h" +#include "MarkStack.h" +#include "Structure.h" +#include <wtf/Noncopyable.h> namespace JSC { @@ -40,19 +41,24 @@ namespace JSC { friend class JSPropertyNameIterator; friend class JSString; friend class JSValue; - friend class VPtrSet; + friend class JSAPIValueWrapper; + friend struct VPtrSet; private: explicit JSCell(Structure*); + JSCell(); // Only used for initializing Collector blocks. virtual ~JSCell(); public: // Querying the type. +#if USE(JSVALUE32) bool isNumber() const; +#endif bool isString() const; bool isObject() const; virtual bool isGetterSetter() const; - virtual bool isObject(const ClassInfo*) const; + bool inherits(const ClassInfo*) const; + virtual bool isAPIValueWrapper() const { return false; } Structure* structure() const; @@ -68,23 +74,21 @@ namespace JSC { // Extracting integer values. // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*. virtual bool getUInt32(uint32_t&) const; - virtual bool getTruncatedInt32(int32_t&) const; - virtual bool getTruncatedUInt32(uint32_t&) const; // Basic conversions. - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const = 0; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&) = 0; - virtual bool toBoolean(ExecState*) const = 0; - virtual double toNumber(ExecState*) const = 0; - virtual UString toString(ExecState*) const = 0; - virtual JSObject* toObject(ExecState*) const = 0; + virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; + virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); + virtual bool toBoolean(ExecState*) const; + virtual double toNumber(ExecState*) const; + virtual UString toString(ExecState*) const; + virtual JSObject* toObject(ExecState*) const; // Garbage collection. void* operator new(size_t, ExecState*); void* operator new(size_t, JSGlobalData*); void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; } - virtual void mark(); - bool marked() const; + + virtual void markChildren(MarkStack&); // Object operations, with the toObject operation included. virtual const ClassInfo* classInfo() const; @@ -108,6 +112,7 @@ namespace JSC { Structure* m_structure; }; + // FIXME: We should deprecate this and just use JSValue::asCell() instead. JSCell* asCell(JSValue); inline JSCell* asCell(JSValue value) @@ -120,14 +125,21 @@ namespace JSC { { } + // Only used for initializing Collector blocks. + inline JSCell::JSCell() + { + } + inline JSCell::~JSCell() { } +#if USE(JSVALUE32) inline bool JSCell::isNumber() const { return Heap::isNumber(const_cast<JSCell*>(this)); } +#endif inline bool JSCell::isObject() const { @@ -144,20 +156,8 @@ namespace JSC { return m_structure; } - inline bool JSCell::marked() const + inline void JSCell::markChildren(MarkStack&) { - return Heap::isCellMarked(this); - } - - inline void JSCell::mark() - { - return Heap::markCell(this); - } - - ALWAYS_INLINE JSCell* JSValue::asCell() const - { - ASSERT(isCell()); - return m_ptr; } inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) @@ -173,126 +173,190 @@ namespace JSC { inline bool JSValue::isString() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isString(); + return isCell() && asCell()->isString(); } inline bool JSValue::isGetterSetter() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter(); + return isCell() && asCell()->isGetterSetter(); } inline bool JSValue::isObject() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(); + return isCell() && asCell()->isObject(); } inline bool JSValue::getString(UString& s) const { - return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s); + return isCell() && asCell()->getString(s); } inline UString JSValue::getString() const { - return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString(); + return isCell() ? asCell()->getString() : UString(); } inline JSObject* JSValue::getObject() const { - return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject(); + return isCell() ? asCell()->getObject() : 0; } inline CallType JSValue::getCallData(CallData& callData) { - return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData); + return isCell() ? asCell()->getCallData(callData) : CallTypeNone; } inline ConstructType JSValue::getConstructData(ConstructData& constructData) { - return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData); + return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone; } ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v); + if (isInt32()) { + int32_t i = asInt32(); + v = static_cast<uint32_t>(i); + return i >= 0; + } + if (isDouble()) { + double d = asDouble(); + v = static_cast<uint32_t>(d); + return v == d; + } + return false; } - ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const +#if !USE(JSVALUE32_64) + ALWAYS_INLINE JSCell* JSValue::asCell() const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v); + ASSERT(isCell()); + return m_ptr; } +#endif // !USE(JSVALUE32_64) - inline bool JSValue::getTruncatedUInt32(uint32_t& v) const + inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v); + return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue(); } - inline void JSValue::mark() + inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) { - asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells + if (isInt32()) { + number = asInt32(); + value = *this; + return true; + } + if (isDouble()) { + number = asDouble(); + value = *this; + return true; + } + if (isCell()) + return asCell()->getPrimitiveNumber(exec, number, value); + if (isTrue()) { + number = 1.0; + value = *this; + return true; + } + if (isFalse() || isNull()) { + number = 0.0; + value = *this; + return true; + } + ASSERT(isUndefined()); + number = nonInlineNaN(); + value = *this; + return true; } - inline bool JSValue::marked() const + inline bool JSValue::toBoolean(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) || asCell()->marked(); + if (isInt32()) + return asInt32() != 0; + if (isDouble()) + return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN + if (isCell()) + return asCell()->toBoolean(exec); + return isTrue(); // false, null, and undefined all convert to false. } - inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const + ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType); + if (isInt32()) + return asInt32(); + if (isDouble()) + return asDouble(); + if (isCell()) + return asCell()->toNumber(exec); + if (isTrue()) + return 1.0; + return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0. } - inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) + inline bool JSValue::needsThisConversion() const { - if (JSImmediate::isImmediate(asValue())) { - number = JSImmediate::toDouble(asValue()); - value = asValue(); + if (UNLIKELY(!isCell())) return true; - } - return asCell()->getPrimitiveNumber(exec, number, value); + return asCell()->structure()->typeInfo().needsThisConversion(); } - inline bool JSValue::toBoolean(ExecState* exec) const + inline UString JSValue::toThisString(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec); + return isCell() ? asCell()->toThisString(exec) : toString(exec); } - ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const + inline JSValue JSValue::getJSNumber() { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec); + if (isInt32() || isDouble()) + return *this; + if (isCell()) + return asCell()->getJSNumber(); + return JSValue(); } - inline UString JSValue::toString(ExecState* exec) const + inline JSObject* JSValue::toObject(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec); + return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec); } - inline JSObject* JSValue::toObject(ExecState* exec) const + inline JSObject* JSValue::toThisObject(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec); + return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec); } - inline JSObject* JSValue::toThisObject(ExecState* exec) const + ALWAYS_INLINE void MarkStack::append(JSCell* cell) { - if (UNLIKELY(JSImmediate::isImmediate(asValue()))) - return JSImmediate::toThisObject(asValue(), exec); - return asCell()->toThisObject(exec); + ASSERT(!m_isCheckingForDefaultMarkViolation); + ASSERT(cell); + if (Heap::isCellMarked(cell)) + return; + Heap::markCell(cell); + if (cell->structure()->typeInfo().type() >= CompoundType) + m_values.append(cell); } - inline bool JSValue::needsThisConversion() const + ALWAYS_INLINE void MarkStack::append(JSValue value) { - if (UNLIKELY(JSImmediate::isImmediate(asValue()))) - return true; - return asCell()->structure()->typeInfo().needsThisConversion(); + ASSERT(value); + if (value.isCell()) + append(value.asCell()); } - inline UString JSValue::toThisString(ExecState* exec) const + inline void Structure::markAggregate(MarkStack& markStack) { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec); + markStack.append(m_prototype); } - inline JSValue JSValue::getJSNumber() + inline Heap* Heap::heap(JSValue v) + { + if (!v.isCell()) + return 0; + return heap(v.asCell()); + } + + inline Heap* Heap::heap(JSCell* c) { - return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? JSValue() : asCell()->getJSNumber(); + return cellBlock(c)->heap; } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp index c8e137e..bf4e34d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * @@ -45,12 +45,21 @@ ASSERT_CLASS_FITS_IN_CELL(JSFunction); const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 }; +bool JSFunction::isHostFunctionNonInline() const +{ + return isHostFunction(); +} + +JSFunction::JSFunction(PassRefPtr<Structure> structure) + : Base(structure) + , m_executable(adoptRef(new VPtrHackExecutable())) +{ +} + JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) : Base(&exec->globalData(), structure, name) #if ENABLE(JIT) - , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData())) -#else - , m_body(0) + , m_executable(adoptRef(new NativeExecutable(exec))) #endif { #if ENABLE(JIT) @@ -63,32 +72,35 @@ JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int len #endif } -JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode) - : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name) - , m_body(body) +JSFunction::JSFunction(ExecState* exec, PassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode) + : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name()) + , m_executable(executable) { setScopeChain(scopeChainNode); } JSFunction::~JSFunction() { -#if ENABLE(JIT) // JIT code for other functions may have had calls linked directly to the code for this function; these links // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once // this memory is freed and may be reused (potentially for another, different JSFunction). - if (m_body && m_body->isGenerated()) - m_body->generatedBytecode().unlinkCallers(); + if (!isHostFunction()) { +#if ENABLE(JIT_OPTIMIZE_CALL) + ASSERT(m_executable); + if (jsExecutable()->isGenerated()) + jsExecutable()->generatedBytecode().unlinkCallers(); #endif - if (!isHostFunction()) - scopeChain().~ScopeChain(); + scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too? + } } -void JSFunction::mark() +void JSFunction::markChildren(MarkStack& markStack) { - Base::mark(); - m_body->mark(); - if (!isHostFunction()) - scopeChain().mark(); + Base::markChildren(markStack); + if (!isHostFunction()) { + jsExecutable()->markAggregate(markStack); + scopeChain().markAggregate(markStack); + } } CallType JSFunction::getCallData(CallData& callData) @@ -97,7 +109,7 @@ CallType JSFunction::getCallData(CallData& callData) callData.native.function = nativeFunction(); return CallTypeHost; } - callData.js.functionBody = m_body.get(); + callData.js.functionExecutable = jsExecutable(); callData.js.scopeChain = scopeChain().node(); return CallTypeJS; } @@ -105,7 +117,7 @@ CallType JSFunction::getCallData(CallData& callData) JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args) { ASSERT(!isHostFunction()); - return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot()); + return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot()); } JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) @@ -126,7 +138,7 @@ JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const Prope { JSFunction* thisObj = asFunction(slot.slotBase()); ASSERT(!thisObj->isHostFunction()); - return jsNumber(exec, thisObj->m_body->parameterCount()); + return jsNumber(exec, thisObj->jsExecutable()->parameterCount()); } bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -165,6 +177,35 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN return Base::getOwnPropertySlot(exec, propertyName, slot); } + bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + if (isHostFunction()) + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + + if (propertyName == exec->propertyNames().prototype) { + PropertySlot slot; + getOwnPropertySlot(exec, propertyName, slot); + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + + if (propertyName == exec->propertyNames().arguments) { + descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete); + return true; + } + + if (propertyName == exec->propertyNames().length) { + descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); + return true; + } + + if (propertyName == exec->propertyNames().caller) { + descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete); + return true; + } + + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { if (isHostFunction()) { @@ -190,7 +231,7 @@ ConstructType JSFunction::getConstructData(ConstructData& constructData) { if (isHostFunction()) return ConstructTypeNone; - constructData.js.functionBody = m_body.get(); + constructData.js.functionExecutable = jsExecutable(); constructData.js.scopeChain = scopeChain().node(); return ConstructTypeJS; } @@ -206,7 +247,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args) structure = exec->lexicalGlobalObject()->emptyObjectStructure(); JSObject* thisObj = new (exec) JSObject(structure); - JSValue result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot()); + JSValue result = exec->interpreter()->execute(jsExecutable(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot()); if (exec->hadException() || !result.isObject()) return thisObj; return asObject(result); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h index 5ddd97c..416a58a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h @@ -25,38 +25,25 @@ #define JSFunction_h #include "InternalFunction.h" -#include "JSVariableObject.h" -#include "SymbolTable.h" -#include "Nodes.h" -#include "JSObject.h" namespace JSC { - class FunctionBodyNode; + class ExecutableBase; + class FunctionExecutable; class FunctionPrototype; class JSActivation; class JSGlobalObject; class JSFunction : public InternalFunction { friend class JIT; - friend class VPtrSet; + friend struct VPtrSet; typedef InternalFunction Base; - JSFunction(PassRefPtr<Structure> structure) - : InternalFunction(structure) - { - clearScopeChain(); - } - public: JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction); - JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*); - ~JSFunction(); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); + JSFunction(ExecState*, PassRefPtr<FunctionExecutable>, ScopeChainNode*); + virtual ~JSFunction(); JSObject* construct(ExecState*, const ArgList&); JSValue call(ExecState*, JSValue thisValue, const ArgList&); @@ -64,11 +51,11 @@ namespace JSC { void setScope(const ScopeChain& scopeChain) { setScopeChain(scopeChain); } ScopeChain& scope() { return scopeChain(); } - void setBody(FunctionBodyNode* body) { m_body = body; } - void setBody(PassRefPtr<FunctionBodyNode> body) { m_body = body; } - FunctionBodyNode* body() const { return m_body.get(); } + ExecutableBase* executable() const { return m_executable.get(); } - virtual void mark(); + // To call either of these methods include Executable.h + inline bool isHostFunction() const; + FunctionExecutable* jsExecutable() const; static JS_EXPORTDATA const ClassInfo info; @@ -77,11 +64,6 @@ namespace JSC { return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); } -#if ENABLE(JIT) - bool isHostFunction() const { return m_body && m_body->isHostFunction(); } -#else - bool isHostFunction() const { return false; } -#endif NativeFunction nativeFunction() { return *reinterpret_cast<NativeFunction*>(m_data); @@ -91,31 +73,42 @@ namespace JSC { virtual CallType getCallData(CallData&); private: + JSFunction(PassRefPtr<Structure>); + + bool isHostFunctionNonInline() const; + + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); + virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); + virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); + + virtual void markChildren(MarkStack&); + virtual const ClassInfo* classInfo() const { return &info; } static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&); static JSValue callerGetter(ExecState*, const Identifier&, const PropertySlot&); static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&); - RefPtr<FunctionBodyNode> m_body; + RefPtr<ExecutableBase> m_executable; ScopeChain& scopeChain() { - ASSERT(!isHostFunction()); + ASSERT(!isHostFunctionNonInline()); return *reinterpret_cast<ScopeChain*>(m_data); } void clearScopeChain() { - ASSERT(!isHostFunction()); + ASSERT(!isHostFunctionNonInline()); new (m_data) ScopeChain(NoScopeChain()); } void setScopeChain(ScopeChainNode* sc) { - ASSERT(!isHostFunction()); + ASSERT(!isHostFunctionNonInline()); new (m_data) ScopeChain(sc); } void setScopeChain(const ScopeChain& sc) { - ASSERT(!isHostFunction()); + ASSERT(!isHostFunctionNonInline()); *reinterpret_cast<ScopeChain*>(m_data) = sc; } void setNativeFunction(NativeFunction func) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp index 85d881e..4496d6c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp @@ -33,14 +33,17 @@ #include "Collector.h" #include "CommonIdentifiers.h" #include "FunctionConstructor.h" +#include "GetterSetter.h" #include "Interpreter.h" #include "JSActivation.h" +#include "JSAPIValueWrapper.h" #include "JSArray.h" #include "JSByteArray.h" #include "JSClassRef.h" #include "JSFunction.h" #include "JSLock.h" #include "JSNotAnObject.h" +#include "JSPropertyNameIterator.h" #include "JSStaticScopeObject.h" #include "Parser.h" #include "Lexer.h" @@ -118,7 +121,10 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet) , stringStructure(JSString::createStructure(jsNull())) , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull())) , notAnObjectStructure(JSNotAnObject::createStructure(jsNull())) -#if !USE(ALTERNATE_JSIMMEDIATE) + , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull())) + , getterSetterStructure(GetterSetter::createStructure(jsNull())) + , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull())) +#if USE(JSVALUE32) , numberStructure(JSNumberCell::createStructure(jsNull())) #endif , jsArrayVPtr(vptrSet.jsArrayVPtr) @@ -139,12 +145,13 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet) , initializingLazyNumericCompareFunction(false) , head(0) , dynamicGlobalObject(0) - , scopeNodeBeingReparsed(0) + , functionCodeBlockBeingReparsed(0) , firstStringifierToMark(0) -{ -#ifdef QT_BUILD_SCRIPT_LIB - scriptpool = new SourcePool(); + , markStack(vptrSet.jsArrayVPtr) +#ifndef NDEBUG + , mainThreadOnly(false) #endif +{ #if PLATFORM(MAC) startProfilerServerIfNeeded(); #endif @@ -190,10 +197,6 @@ JSGlobalData::~JSGlobalData() deleteIdentifierTable(identifierTable); delete clientData; -#ifdef QT_BUILD_SCRIPT_LIB - if (scriptpool) - delete scriptpool; -#endif } PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared) @@ -238,9 +241,8 @@ const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec) { if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) { initializingLazyNumericCompareFunction = true; - RefPtr<ProgramNode> programNode = parser->parse<ProgramNode>(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0); - RefPtr<FunctionBodyNode> functionBody = extractFunctionBody(programNode.get()); - lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions(); + RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(Identifier(exec, "numericCompare"), exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0); + lazyNumericCompareFunction = function->bytecode(exec, exec->scopeChain()).instructions(); initializingLazyNumericCompareFunction = false; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h index fb557af..c9887e8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h @@ -33,36 +33,33 @@ #include "ExecutableAllocator.h" #include "JITStubs.h" #include "JSValue.h" +#include "MarkStack.h" +#include "NumericStrings.h" #include "SmallStrings.h" #include "TimeoutChecker.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> -#ifdef QT_BUILD_SCRIPT_LIB -#include "SourcePoolQt.h" -#endif - struct OpaqueJSClass; struct OpaqueJSClassContextData; namespace JSC { + class CodeBlock; class CommonIdentifiers; - class FunctionBodyNode; class IdentifierTable; - class Instruction; class Interpreter; class JSGlobalObject; class JSObject; class Lexer; class Parser; - class ScopeNode; class Stringifier; class Structure; class UString; struct HashTable; + struct Instruction; struct VPtrSet; class JSGlobalData : public RefCounted<JSGlobalData> { @@ -70,7 +67,7 @@ namespace JSC { struct ClientData { virtual ~ClientData() = 0; #ifdef QT_BUILD_SCRIPT_LIB - virtual void mark() {} + virtual void mark(MarkStack&) {} #endif }; @@ -104,7 +101,11 @@ namespace JSC { RefPtr<Structure> stringStructure; RefPtr<Structure> notAnObjectErrorStubStructure; RefPtr<Structure> notAnObjectStructure; -#if !USE(ALTERNATE_JSIMMEDIATE) + RefPtr<Structure> propertyNameIteratorStructure; + RefPtr<Structure> getterSetterStructure; + RefPtr<Structure> apiWrapperStructure; + +#if USE(JSVALUE32) RefPtr<Structure> numberStructure; #endif @@ -117,6 +118,7 @@ namespace JSC { CommonIdentifiers* propertyNames; 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; #if ENABLE(ASSEMBLER) ExecutableAllocator executableAllocator; @@ -125,9 +127,6 @@ namespace JSC { Lexer* lexer; Parser* parser; Interpreter* interpreter; -#ifdef QT_BUILD_SCRIPT_LIB - SourcePool* scriptpool; -#endif #if ENABLE(JIT) JITThunks jitStubs; #endif @@ -150,9 +149,15 @@ namespace JSC { HashSet<JSObject*> arrayVisitedElements; - ScopeNode* scopeNodeBeingReparsed; + CodeBlock* functionCodeBlockBeingReparsed; Stringifier* firstStringifierToMark; + MarkStack markStack; + +#ifndef NDEBUG + bool mainThreadOnly; +#endif + private: JSGlobalData(bool isShared, const VPtrSet&); static JSGlobalData*& sharedInstanceInternal(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp index 55286d3..60eb1b4 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -80,16 +80,16 @@ static const int initialTickCountThreshold = 255; // Preferred number of milliseconds between each timeout check static const int preferredScriptCheckTimeInterval = 1000; -static inline void markIfNeeded(JSValue v) +static inline void markIfNeeded(MarkStack& markStack, JSValue v) { - if (v && !v.marked()) - v.mark(); + if (v) + markStack.append(v); } -static inline void markIfNeeded(const RefPtr<Structure>& s) +static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) { if (s) - s->mark(); + s->markAggregate(markStack); } JSGlobalObject::~JSGlobalObject() @@ -112,8 +112,8 @@ JSGlobalObject::~JSGlobalObject() if (headObject == this) headObject = 0; - HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end(); - for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) + HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); + for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) (*it)->clearGlobalObject(); RegisterFile& registerFile = globalData()->interpreter->registerFile(); @@ -175,18 +175,18 @@ void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& proper } } -void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc) +void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) { PropertySlot slot; if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineGetter(exec, propertyName, getterFunc); + JSVariableObject::defineGetter(exec, propertyName, getterFunc, attributes); } -void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc) +void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) { PropertySlot slot; if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineSetter(exec, propertyName, setterFunc); + JSVariableObject::defineSetter(exec, propertyName, setterFunc, attributes); } static inline JSObject* lastInPrototypeChain(JSObject* object) @@ -256,9 +256,9 @@ void JSGlobalObject::reset(JSValue prototype) // Constructors - JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype); + JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get()); JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype); - JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype); + JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get()); JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype); JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype); JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype); @@ -359,43 +359,43 @@ void JSGlobalObject::resetPrototype(JSValue prototype) oldLastInPrototypeChain->setPrototype(objectPrototype); } -void JSGlobalObject::mark() +void JSGlobalObject::markChildren(MarkStack& markStack) { - JSVariableObject::mark(); + JSVariableObject::markChildren(markStack); - HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end(); - for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) - (*it)->mark(); + HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); + for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) + (*it)->markAggregate(markStack); RegisterFile& registerFile = globalData()->interpreter->registerFile(); if (registerFile.globalObject() == this) - registerFile.markGlobals(&globalData()->heap); - - markIfNeeded(d()->regExpConstructor); - markIfNeeded(d()->errorConstructor); - markIfNeeded(d()->evalErrorConstructor); - markIfNeeded(d()->rangeErrorConstructor); - markIfNeeded(d()->referenceErrorConstructor); - markIfNeeded(d()->syntaxErrorConstructor); - markIfNeeded(d()->typeErrorConstructor); - markIfNeeded(d()->URIErrorConstructor); - - markIfNeeded(d()->evalFunction); - markIfNeeded(d()->callFunction); - markIfNeeded(d()->applyFunction); - - markIfNeeded(d()->objectPrototype); - markIfNeeded(d()->functionPrototype); - markIfNeeded(d()->arrayPrototype); - markIfNeeded(d()->booleanPrototype); - markIfNeeded(d()->stringPrototype); - markIfNeeded(d()->numberPrototype); - markIfNeeded(d()->datePrototype); - markIfNeeded(d()->regExpPrototype); - - markIfNeeded(d()->methodCallDummy); - - markIfNeeded(d()->errorStructure); + registerFile.markGlobals(markStack, &globalData()->heap); + + markIfNeeded(markStack, d()->regExpConstructor); + markIfNeeded(markStack, d()->errorConstructor); + markIfNeeded(markStack, d()->evalErrorConstructor); + markIfNeeded(markStack, d()->rangeErrorConstructor); + markIfNeeded(markStack, d()->referenceErrorConstructor); + markIfNeeded(markStack, d()->syntaxErrorConstructor); + markIfNeeded(markStack, d()->typeErrorConstructor); + markIfNeeded(markStack, d()->URIErrorConstructor); + + markIfNeeded(markStack, d()->evalFunction); + markIfNeeded(markStack, d()->callFunction); + markIfNeeded(markStack, d()->applyFunction); + + markIfNeeded(markStack, d()->objectPrototype); + markIfNeeded(markStack, d()->functionPrototype); + markIfNeeded(markStack, d()->arrayPrototype); + markIfNeeded(markStack, d()->booleanPrototype); + markIfNeeded(markStack, d()->stringPrototype); + markIfNeeded(markStack, d()->numberPrototype); + markIfNeeded(markStack, d()->datePrototype); + markIfNeeded(markStack, d()->regExpPrototype); + + markIfNeeded(markStack, d()->methodCallDummy); + + markIfNeeded(markStack, d()->errorStructure); // No need to mark the other structures, because their prototypes are all // guaranteed to be referenced elsewhere. @@ -405,11 +405,7 @@ void JSGlobalObject::mark() return; size_t size = d()->registerArraySize; - for (size_t i = 0; i < size; ++i) { - Register& r = registerArray[i]; - if (!r.marked()) - r.mark(); - } + markStack.appendValues(reinterpret_cast<JSValue*>(registerArray), size); } ExecState* JSGlobalObject::globalExec() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h index 98e9b68..7459c2e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,10 +31,6 @@ #include <wtf/HashSet.h> #include <wtf/OwnPtr.h> -#ifdef QT_BUILD_SCRIPT_LIB -#include "SourcePoolQt.h" -#endif - namespace JSC { class ArrayPrototype; @@ -43,6 +39,7 @@ namespace JSC { class Debugger; class ErrorConstructor; class FunctionPrototype; + class GlobalCodeBlock; class GlobalEvalFunction; class NativeErrorConstructor; class ProgramCodeBlock; @@ -149,7 +146,7 @@ namespace JSC { RefPtr<JSGlobalData> globalData; - HashSet<ProgramCodeBlock*> codeBlocks; + HashSet<GlobalCodeBlock*> codeBlocks; }; public: @@ -171,15 +168,16 @@ namespace JSC { public: virtual ~JSGlobalObject(); - virtual void mark(); + virtual void markChildren(MarkStack&); virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&); virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes); - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes); // Linked list of all global objects that use the same JSGlobalData. JSGlobalObject*& head() { return d()->globalData->head; } @@ -233,9 +231,6 @@ namespace JSC { Debugger* debugger() const { return d()->debugger; } void setDebugger(Debugger* debugger) { -#ifdef QT_BUILD_SCRIPT_LIB - globalData()->scriptpool->setDebugger(debugger); -#endif d()->debugger = debugger; } @@ -257,7 +252,7 @@ namespace JSC { virtual bool isDynamicScope() const; - HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; } + HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; } void copyGlobalsFrom(RegisterFile&); void copyGlobalsTo(RegisterFile&); @@ -336,6 +331,13 @@ namespace JSC { return symbolTableGet(propertyName, slot); } + inline bool JSGlobalObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + if (symbolTableGet(propertyName, descriptor)) + return true; + return JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName) { PropertySlot slot; @@ -358,11 +360,16 @@ namespace JSC { if (typeInfo().type() == ObjectType) return m_prototype; +#if USE(JSVALUE32) if (typeInfo().type() == StringType) return exec->lexicalGlobalObject()->stringPrototype(); ASSERT(typeInfo().type() == NumberType); return exec->lexicalGlobalObject()->numberPrototype(); +#else + ASSERT(typeInfo().type() == StringType); + return exec->lexicalGlobalObject()->stringPrototype(); +#endif } inline StructureChain* Structure::prototypeChain(ExecState* exec) const diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index 85f92f2..b11070f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -286,16 +286,12 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; - int errLine; - UString errMsg; + EvalExecutable eval(makeSource(s)); + JSObject* error = eval.compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node()); + if (error) + return throwError(exec, error); - SourceCode source = makeSource(s); - RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - - if (!evalNode) - return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL); - - return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot()); + return exec->interpreter()->execute(&eval, exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot()); } JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args) @@ -303,14 +299,18 @@ JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, co JSValue value = args.at(0); int32_t radix = args.at(1).toInt32(exec); - if (value.isNumber() && (radix == 0 || radix == 10)) { - if (value.isInt32Fast()) - return value; - double d = value.uncheckedGetNumber(); + if (radix != 0 && radix != 10) + return jsNumber(exec, parseInt(value.toString(exec), radix)); + + if (value.isInt32()) + return value; + + if (value.isDouble()) { + double d = value.asDouble(); if (isfinite(d)) return jsNumber(exec, (d > 0) ? floor(d) : ceil(d)); if (isnan(d) || isinf(d)) - return jsNaN(&exec->globalData()); + return jsNaN(exec); return jsNumber(exec, 0); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp index 201e56c..846238d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp @@ -21,83 +21,6 @@ #include "config.h" #include "JSImmediate.h" -#include "BooleanConstructor.h" -#include "BooleanPrototype.h" -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSGlobalObject.h" -#include "JSNotAnObject.h" -#include "NumberConstructor.h" -#include "NumberPrototype.h" - namespace JSC { -JSObject* JSImmediate::toThisObject(JSValue v, ExecState* exec) -{ - ASSERT(isImmediate(v)); - if (isNumber(v)) - return constructNumber(exec, v); - if (isBoolean(v)) - return constructBooleanFromImmediateBoolean(exec, v); - ASSERT(v.isUndefinedOrNull()); - return exec->globalThisValue(); -} - -JSObject* JSImmediate::toObject(JSValue v, ExecState* exec) -{ - ASSERT(isImmediate(v)); - if (isNumber(v)) - return constructNumber(exec, v); - if (isBoolean(v)) - return constructBooleanFromImmediateBoolean(exec, v); - - JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull()); - exec->setException(exception); - return new (exec) JSNotAnObject(exec, exception); -} - -JSObject* JSImmediate::prototype(JSValue v, ExecState* exec) -{ - ASSERT(isImmediate(v)); - if (isNumber(v)) - return exec->lexicalGlobalObject()->numberPrototype(); - if (isBoolean(v)) - return exec->lexicalGlobalObject()->booleanPrototype(); - - JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull()); - exec->setException(exception); - return new (exec) JSNotAnObject(exec, exception); -} - -UString JSImmediate::toString(JSValue v) -{ - ASSERT(isImmediate(v)); - if (isIntegerNumber(v)) - return UString::from(getTruncatedInt32(v)); -#if USE(ALTERNATE_JSIMMEDIATE) - if (isNumber(v)) { - ASSERT(isDoubleNumber(v)); - double value = doubleValue(v); - if (value == 0.0) // +0.0 or -0.0 - return "0"; - return UString::from(value); - } -#else - ASSERT(!isNumber(v)); -#endif - if (jsBoolean(false) == v) - return "false"; - if (jsBoolean(true) == v) - return "true"; - if (v.isNull()) - return "null"; - ASSERT(v.isUndefined()); - return "undefined"; -} - -NEVER_INLINE double JSImmediate::nonInlineNaN() -{ - return std::numeric_limits<double>::quiet_NaN(); -} - } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h index e7d7847..053b4c0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h @@ -22,6 +22,10 @@ #ifndef JSImmediate_h #define JSImmediate_h +#include <wtf/Platform.h> + +#if !USE(JSVALUE32_64) + #include <wtf/Assertions.h> #include <wtf/AlwaysInline.h> #include <wtf/MathExtras.h> @@ -42,7 +46,7 @@ namespace JSC { class JSObject; class UString; -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) inline intptr_t reinterpretDoubleToIntptr(double value) { return WTF::bitwise_cast<intptr_t>(value); @@ -98,7 +102,7 @@ namespace JSC { /* * On 64-bit platforms, we support an alternative encoding form for immediates, if - * USE(ALTERNATE_JSIMMEDIATE) is defined. When this format is used, double precision + * USE(JSVALUE64) is defined. When this format is used, double precision * floating point values may also be encoded as JSImmediates. * * The encoding makes use of unused NaN space in the IEEE754 representation. Any value @@ -159,7 +163,7 @@ namespace JSC { friend JSValue jsNumber(JSGlobalData* globalData, long long i); friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) // If all bits in the mask are set, this indicates an integer number, // if any but not all are set this value is a double precision number. static const intptr_t TagTypeNumber = 0xffff000000000000ll; @@ -181,7 +185,7 @@ namespace JSC { static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined; static const intptr_t FullTagTypeNull = TagBitTypeOther; -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) static const int32_t IntegerPayloadShift = 0; #else static const int32_t IntegerPayloadShift = 1; @@ -204,15 +208,15 @@ namespace JSC { static ALWAYS_INLINE bool isIntegerNumber(JSValue v) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return (rawValue(v) & TagTypeNumber) == TagTypeNumber; #else return isNumber(v); #endif } -#if USE(ALTERNATE_JSIMMEDIATE) - static ALWAYS_INLINE bool isDoubleNumber(JSValue v) +#if USE(JSVALUE64) + static ALWAYS_INLINE bool isDouble(JSValue v) { return isNumber(v) && !isIntegerNumber(v); } @@ -260,7 +264,7 @@ namespace JSC { static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2) { -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber; #else return rawValue(v1) & rawValue(v2) & TagTypeNumber; @@ -269,9 +273,6 @@ namespace JSC { static double toDouble(JSValue); static bool toBoolean(JSValue); - static JSObject* toObject(JSValue, ExecState*); - static JSObject* toThisObject(JSValue, ExecState*); - static UString toString(JSValue); static bool getUInt32(JSValue, uint32_t&); static bool getTruncatedInt32(JSValue, int32_t&); @@ -287,10 +288,8 @@ namespace JSC { static JSValue zeroImmediate(); static JSValue oneImmediate(); - static JSObject* prototype(JSValue, ExecState*); - private: -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) static const int minImmediateInt = ((-INT_MAX) - 1); static const int maxImmediateInt = INT_MAX; #else @@ -304,10 +303,10 @@ namespace JSC { return JSValue::makeImmediate(integer); } - // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the + // With USE(JSVALUE64) we want the argument to be zero extended, so the // integer doesn't interfere with the tag bits in the upper word. In the default encoding, // if intptr_t id larger then int32_t we sign extend the value through the upper word. -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) static ALWAYS_INLINE JSValue makeInt(uint32_t value) #else static ALWAYS_INLINE JSValue makeInt(int32_t value) @@ -316,7 +315,7 @@ namespace JSC { return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber); } -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) static ALWAYS_INLINE JSValue makeDouble(double value) { return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset); @@ -341,7 +340,7 @@ namespace JSC { template<typename T> static JSValue fromNumberOutsideIntegerRange(T); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) static ALWAYS_INLINE double doubleValue(JSValue v) { return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset); @@ -367,8 +366,6 @@ namespace JSC { { return v.immediateValue(); } - - static double nonInlineNaN(); }; ALWAYS_INLINE JSValue JSImmediate::trueImmediate() { return makeBool(true); } @@ -378,7 +375,7 @@ namespace JSC { ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); } ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); } -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) inline bool doubleToBoolean(double value) { return value < 0.0 || value > 0.0; @@ -405,7 +402,7 @@ namespace JSC { return intValue(v); } -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) template<typename T> inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value) { @@ -446,7 +443,7 @@ namespace JSC { ALWAYS_INLINE JSValue JSImmediate::from(int i) { -#if !USE(ALTERNATE_JSIMMEDIATE) +#if !USE(JSVALUE64) if ((i < minImmediateInt) | (i > maxImmediateInt)) return fromNumberOutsideIntegerRange(i); #endif @@ -512,9 +509,9 @@ namespace JSC { if (isIntegerNumber(v)) return intValue(v); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) if (isNumber(v)) { - ASSERT(isDoubleNumber(v)); + ASSERT(isDouble(v)); return doubleValue(v); } #else @@ -545,12 +542,6 @@ namespace JSC { return getUInt32(v, i); } - // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32(). - int32_t toInt32(double); - uint32_t toUInt32(double); - int32_t toInt32SlowCase(double, bool& ok); - uint32_t toUInt32SlowCase(double, bool& ok); - inline JSValue::JSValue(JSNullTag) { *this = JSImmediate::nullImmediate(); @@ -581,6 +572,16 @@ namespace JSC { return JSImmediate::isBoolean(asValue()); } + inline bool JSValue::isTrue() const + { + return asValue() == JSImmediate::trueImmediate(); + } + + inline bool JSValue::isFalse() const + { + return asValue() == JSImmediate::falseImmediate(); + } + inline bool JSValue::getBoolean(bool& v) const { if (JSImmediate::isBoolean(asValue())) { @@ -596,99 +597,33 @@ namespace JSC { return asValue() == jsBoolean(true); } - ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const - { - int32_t i; - if (getTruncatedInt32(i)) - return i; - bool ignored; - return toInt32SlowCase(toNumber(exec), ignored); - } - - inline uint32_t JSValue::toUInt32(ExecState* exec) const - { - uint32_t i; - if (getTruncatedUInt32(i)) - return i; - bool ignored; - return toUInt32SlowCase(toNumber(exec), ignored); - } - - inline int32_t toInt32(double val) - { - if (!(val >= -2147483648.0 && val < 2147483648.0)) { - bool ignored; - return toInt32SlowCase(val, ignored); - } - return static_cast<int32_t>(val); - } - - inline uint32_t toUInt32(double val) - { - if (!(val >= 0.0 && val < 4294967296.0)) { - bool ignored; - return toUInt32SlowCase(val, ignored); - } - return static_cast<uint32_t>(val); - } - - inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const - { - int32_t i; - if (getTruncatedInt32(i)) { - ok = true; - return i; - } - return toInt32SlowCase(toNumber(exec), ok); - } - - inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const - { - uint32_t i; - if (getTruncatedUInt32(i)) { - ok = true; - return i; - } - return toUInt32SlowCase(toNumber(exec), ok); - } - inline bool JSValue::isCell() const { return !JSImmediate::isImmediate(asValue()); } - inline bool JSValue::isInt32Fast() const + inline bool JSValue::isInt32() const { return JSImmediate::isIntegerNumber(asValue()); } - inline int32_t JSValue::getInt32Fast() const + inline int32_t JSValue::asInt32() const { - ASSERT(isInt32Fast()); + ASSERT(isInt32()); return JSImmediate::getTruncatedInt32(asValue()); } - inline bool JSValue::isUInt32Fast() const + inline bool JSValue::isUInt32() const { return JSImmediate::isPositiveIntegerNumber(asValue()); } - inline uint32_t JSValue::getUInt32Fast() const + inline uint32_t JSValue::asUInt32() const { - ASSERT(isUInt32Fast()); + ASSERT(isUInt32()); return JSImmediate::getTruncatedUInt32(asValue()); } - inline JSValue JSValue::makeInt32Fast(int32_t i) - { - return JSImmediate::from(i); - } - - inline bool JSValue::areBothInt32Fast(JSValue v1, JSValue v2) - { - return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); - } - class JSFastMath { public: static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValue v1, JSValue v2) @@ -739,7 +674,7 @@ namespace JSC { static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift) { ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift)); -#if USE(ALTERNATE_JSIMMEDIATE) +#if USE(JSVALUE64) return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber); #else return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber); @@ -787,4 +722,6 @@ namespace JSC { } // namespace JSC +#endif // !USE(JSVALUE32_64) + #endif // JSImmediate_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp index fb9cfe8..321762a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -74,11 +74,10 @@ JSObject* JSNotAnObject::toObject(ExecState* exec) const } // Marking -void JSNotAnObject::mark() +void JSNotAnObject::markChildren(MarkStack& markStack) { - JSCell::mark(); - if (!m_exception->marked()) - m_exception->mark(); + JSObject::markChildren(markStack); + markStack.append(m_exception); } // JSObject methods @@ -94,6 +93,12 @@ bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&) return false; } +bool JSNotAnObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier&, PropertyDescriptor&) +{ + ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception); + return false; +} + void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&) { ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception); @@ -116,7 +121,7 @@ bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned) return false; } -void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&, unsigned) +void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, bool) { ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h index 0aca63b..57347af 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -75,11 +75,12 @@ namespace JSC { virtual JSObject* toObject(ExecState*) const; // Marking - virtual void mark(); + virtual void markChildren(MarkStack&); // JSObject methods virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual void put(ExecState*, unsigned propertyName, JSValue); @@ -87,7 +88,7 @@ namespace JSC { virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); JSNotAnObjectErrorStub* m_exception; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp index 669440b..f1009b9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp @@ -23,13 +23,13 @@ #include "config.h" #include "JSNumberCell.h" +#if USE(JSVALUE32) + #include "NumberObject.h" #include "UString.h" namespace JSC { -#if !USE(ALTERNATE_JSIMMEDIATE) - JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const { return const_cast<JSNumberCell*>(this); @@ -54,15 +54,11 @@ double JSNumberCell::toNumber(ExecState*) const UString JSNumberCell::toString(ExecState*) const { - if (m_value == 0.0) // +0.0 or -0.0 - return "0"; return UString::from(m_value); } UString JSNumberCell::toThisString(ExecState*) const { - if (m_value == 0.0) // +0.0 or -0.0 - return "0"; return UString::from(m_value); } @@ -82,22 +78,6 @@ bool JSNumberCell::getUInt32(uint32_t& uint32) const return uint32 == m_value; } -bool JSNumberCell::getTruncatedInt32(int32_t& int32) const -{ - if (!(m_value >= -2147483648.0 && m_value < 2147483648.0)) - return false; - int32 = static_cast<int32_t>(m_value); - return true; -} - -bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const -{ - if (!(m_value >= 0.0 && m_value < 4294967296.0)) - return false; - uint32 = static_cast<uint32_t>(m_value); - return true; -} - JSValue JSNumberCell::getJSNumber() { return this; @@ -113,25 +93,21 @@ JSValue jsNumberCell(JSGlobalData* globalData, double d) return new (globalData) JSNumberCell(globalData, d); } -JSValue jsAPIMangledNumber(ExecState* exec, double d) -{ - return new (exec) JSNumberCell(JSNumberCell::APIMangled, d); -} +} // namespace JSC -#else +#else // USE(JSVALUE32) -JSValue jsNumberCell(ExecState*, double) -{ - ASSERT_NOT_REACHED(); - return JSValue(); -} +// Keep our exported symbols lists happy. +namespace JSC { + +JSValue jsNumberCell(ExecState*, double); -JSValue jsAPIMangledNumber(ExecState*, double) +JSValue jsNumberCell(ExecState*, double) { ASSERT_NOT_REACHED(); return JSValue(); } -#endif - } // namespace JSC + +#endif // USE(JSVALUE32) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h index a35e210..6a48081 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h @@ -35,10 +35,8 @@ namespace JSC { extern const double NaN; extern const double Inf; +#if USE(JSVALUE32) JSValue jsNumberCell(ExecState*, double); - JSValue jsAPIMangledNumber(ExecState*, double); - -#if !USE(ALTERNATE_JSIMMEDIATE) class Identifier; class JSCell; @@ -53,7 +51,7 @@ namespace JSC { friend class JIT; friend JSValue jsNumberCell(JSGlobalData*, double); friend JSValue jsNumberCell(ExecState*, double); - friend JSValue jsAPIMangledNumber(ExecState*, double); + public: double value() const { return m_value; } @@ -68,9 +66,6 @@ namespace JSC { virtual JSObject* toThisObject(ExecState*) const; virtual JSValue getJSNumber(); - static const uintptr_t JSAPIMangledMagicNumber = 0xbbadbeef; - bool isAPIMangledNumber() const { return m_structure == reinterpret_cast<Structure*>(JSAPIMangledMagicNumber); } - void* operator new(size_t size, ExecState* exec) { #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE @@ -89,7 +84,7 @@ namespace JSC { #endif } - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); } private: JSNumberCell(JSGlobalData* globalData, double value) @@ -104,16 +99,7 @@ namespace JSC { { } - enum APIMangledTag { APIMangled }; - JSNumberCell(APIMangledTag, double value) - : JSCell(reinterpret_cast<Structure*>(JSAPIMangledMagicNumber)) - , m_value(value) - { - } - virtual bool getUInt32(uint32_t&) const; - virtual bool getTruncatedInt32(int32_t&) const; - virtual bool getTruncatedUInt32(uint32_t&) const; double m_value; }; @@ -131,7 +117,6 @@ namespace JSC { return static_cast<JSNumberCell*>(v.asCell()); } - inline JSValue::JSValue(ExecState* exec, double d) { JSValue v = JSImmediate::from(d); @@ -192,59 +177,30 @@ namespace JSC { *this = v ? v : jsNumberCell(globalData, i); } - inline JSValue::JSValue(JSGlobalData* globalData, long i) - { - JSValue v = JSImmediate::from(i); - *this = v ? v : jsNumberCell(globalData, i); - } - - inline JSValue::JSValue(JSGlobalData* globalData, unsigned long i) - { - JSValue v = JSImmediate::from(i); - *this = v ? v : jsNumberCell(globalData, i); - } - - inline JSValue::JSValue(JSGlobalData* globalData, long long i) - { - JSValue v = JSImmediate::from(i); - *this = v ? v : jsNumberCell(globalData, static_cast<double>(i)); - } - - inline JSValue::JSValue(JSGlobalData* globalData, unsigned long long i) - { - JSValue v = JSImmediate::from(i); - *this = v ? v : jsNumberCell(globalData, static_cast<double>(i)); - } - - inline bool JSValue::isDoubleNumber() const + inline bool JSValue::isDouble() const { return isNumberCell(asValue()); } - inline double JSValue::getDoubleNumber() const + inline double JSValue::asDouble() const { return asNumberCell(asValue())->value(); } inline bool JSValue::isNumber() const { - return JSImmediate::isNumber(asValue()) || isDoubleNumber(); + return JSImmediate::isNumber(asValue()) || isDouble(); } inline double JSValue::uncheckedGetNumber() const { ASSERT(isNumber()); - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber(); + return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble(); } - inline bool JSValue::isAPIMangledNumber() - { - ASSERT(isNumber()); - return JSImmediate::isImmediate(asValue()) ? false : asNumberCell(asValue())->isAPIMangledNumber(); - } - -#else +#endif // USE(JSVALUE32) +#if USE(JSVALUE64) inline JSValue::JSValue(ExecState*, double d) { JSValue v = JSImmediate::from(d); @@ -315,40 +271,12 @@ namespace JSC { *this = v; } - inline JSValue::JSValue(JSGlobalData*, long i) - { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(JSGlobalData*, unsigned long i) + inline bool JSValue::isDouble() const { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(JSGlobalData*, long long i) - { - JSValue v = JSImmediate::from(static_cast<double>(i)); - ASSERT(v); - *this = v; + return JSImmediate::isDouble(asValue()); } - inline JSValue::JSValue(JSGlobalData*, unsigned long long i) - { - JSValue v = JSImmediate::from(static_cast<double>(i)); - ASSERT(v); - *this = v; - } - - inline bool JSValue::isDoubleNumber() const - { - return JSImmediate::isDoubleNumber(asValue()); - } - - inline double JSValue::getDoubleNumber() const + inline double JSValue::asDouble() const { return JSImmediate::doubleValue(asValue()); } @@ -364,7 +292,9 @@ namespace JSC { return JSImmediate::toDouble(asValue()); } -#endif +#endif // USE(JSVALUE64) + +#if USE(JSVALUE32) || USE(JSVALUE64) inline JSValue::JSValue(ExecState*, char i) { @@ -390,30 +320,6 @@ namespace JSC { *this = JSImmediate::from(i); } - inline JSValue::JSValue(JSGlobalData*, char i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(JSGlobalData*, unsigned char i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(JSGlobalData*, short i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(JSGlobalData*, unsigned short i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - inline JSValue jsNaN(ExecState* exec) { return jsNumber(exec, NaN); @@ -433,23 +339,10 @@ namespace JSC { inline bool JSValue::getNumber(double &result) const { - if (isInt32Fast()) - result = getInt32Fast(); - else if (LIKELY(isDoubleNumber())) - result = getDoubleNumber(); - else { - ASSERT(!isNumber()); - return false; - } - return true; - } - - inline bool JSValue::numberToInt32(int32_t& arg) - { - if (isInt32Fast()) - arg = getInt32Fast(); - else if (LIKELY(isDoubleNumber())) - arg = JSC::toInt32(getDoubleNumber()); + if (isInt32()) + result = asInt32(); + else if (LIKELY(isDouble())) + result = asDouble(); else { ASSERT(!isNumber()); return false; @@ -457,23 +350,7 @@ namespace JSC { return true; } - inline bool JSValue::numberToUInt32(uint32_t& arg) - { - if (isUInt32Fast()) - arg = getUInt32Fast(); - else if (LIKELY(isDoubleNumber())) - arg = JSC::toUInt32(getDoubleNumber()); - else if (isInt32Fast()) { - // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase - // on a negative value is equivalent to simple static_casting. - bool ignored; - arg = toUInt32SlowCase(getInt32Fast(), ignored); - } else { - ASSERT(!isNumber()); - return false; - } - return true; - } +#endif // USE(JSVALUE32) || USE(JSVALUE64) } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp index bbbe3af..377c9d1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp @@ -67,7 +67,7 @@ public: ~Stringifier(); JSValue stringify(JSValue); - void mark(); + void markAggregate(MarkStack&); private: typedef UString StringBuilder; @@ -120,38 +120,47 @@ private: // ------------------------------ helper functions -------------------------------- -static inline JSValue unwrapBoxedPrimitive(JSValue value) +static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value) { if (!value.isObject()) return value; - if (!asObject(value)->inherits(&NumberObject::info) && !asObject(value)->inherits(&StringObject::info) && !asObject(value)->inherits(&BooleanObject::info)) - return value; - return static_cast<JSWrapperObject*>(asObject(value))->internalValue(); + JSObject* object = asObject(value); + if (object->inherits(&NumberObject::info)) + return jsNumber(exec, object->toNumber(exec)); + if (object->inherits(&StringObject::info)) + return jsString(exec, object->toString(exec)); + if (object->inherits(&BooleanObject::info)) + return object->toPrimitive(exec); + return value; } -static inline UString gap(JSValue space) +static inline UString gap(ExecState* exec, JSValue space) { - space = unwrapBoxedPrimitive(space); + const int maxGapLength = 10; + space = unwrapBoxedPrimitive(exec, space); // If the space value is a number, create a gap string with that number of spaces. double spaceCount; if (space.getNumber(spaceCount)) { - const int maxSpaceCount = 100; int count; - if (spaceCount > maxSpaceCount) - count = maxSpaceCount; + if (spaceCount > maxGapLength) + count = maxGapLength; else if (!(spaceCount > 0)) count = 0; else count = static_cast<int>(spaceCount); - UChar spaces[maxSpaceCount]; + UChar spaces[maxGapLength]; for (int i = 0; i < count; ++i) spaces[i] = ' '; return UString(spaces, count); } // If the space value is a string, use it as the gap string, otherwise use no gap string. - return space.getString(); + UString spaces = space.getString(); + if (spaces.size() > maxGapLength) { + spaces = spaces.substr(0, maxGapLength); + } + return spaces; } // ------------------------------ PropertyNameForFunctionCall -------------------------------- @@ -187,7 +196,7 @@ Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space) , m_usingArrayReplacer(false) , m_arrayReplacerPropertyNames(exec) , m_replacerCallType(CallTypeNone) - , m_gap(gap(space)) + , m_gap(gap(exec, space)) { exec->globalData().firstStringifierToMark = this; @@ -202,12 +211,27 @@ Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space) JSValue name = array->get(exec, i); if (exec->hadException()) break; + UString propertyName; - if (!name.getString(propertyName)) + if (name.getString(propertyName)) { + m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); continue; - if (exec->hadException()) - return; - m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); + } + + double value = 0; + if (name.getNumber(value)) { + m_arrayReplacerPropertyNames.add(Identifier::from(exec, value)); + continue; + } + + if (name.isObject()) { + if (!asObject(name)->inherits(&NumberObject::info) && !asObject(name)->inherits(&StringObject::info)) + continue; + propertyName = name.toString(exec); + if (exec->hadException()) + break; + m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); + } } return; } @@ -221,15 +245,12 @@ Stringifier::~Stringifier() m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark; } -void Stringifier::mark() +void Stringifier::markAggregate(MarkStack& markStack) { for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) { size_t size = m_holderStack.size(); - for (size_t i = 0; i < size; ++i) { - JSObject* object = m_holderStack[i].object(); - if (!object->marked()) - object->mark(); - } + for (size_t i = 0; i < size; ++i) + markStack.append(m_holderStack[i].object()); } } @@ -339,8 +360,6 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& value = toJSON(value, propertyName); if (m_exec->hadException()) return StringifyFailed; - if (value.isUndefined() && !holder->inherits(&JSArray::info)) - return StringifyFailedDueToUndefinedValue; // Call the replacer function. if (m_replacerCallType != CallTypeNone) { @@ -351,12 +370,18 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& return StringifyFailed; } + if (value.isUndefined() && !holder->inherits(&JSArray::info)) + return StringifyFailedDueToUndefinedValue; + if (value.isNull()) { builder.append("null"); return StringifySucceeded; } - value = unwrapBoxedPrimitive(value); + value = unwrapBoxedPrimitive(m_exec, value); + + if (m_exec->hadException()) + return StringifyFailed; if (value.isBoolean()) { builder.append(value.getBoolean() ? "true" : "false"); @@ -383,9 +408,18 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& JSObject* object = asObject(value); + CallData callData; + if (object->getCallData(callData) != CallTypeNone) { + if (holder->inherits(&JSArray::info)) { + builder.append("null"); + return StringifySucceeded; + } + return StringifyFailedDueToUndefinedValue; + } + // Handle cycle detection, and put the holder on the stack. if (!m_holderCycleDetector.add(object).second) { - throwError(m_exec, TypeError); + throwError(m_exec, TypeError, "JSON.stringify cannot serialize cyclic structures."); return StringifyFailed; } bool holderStackWasEmpty = m_holderStack.isEmpty(); @@ -394,7 +428,9 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& return StringifySucceeded; // If this is the outermost call, then loop to handle everything on the holder stack. - TimeoutChecker localTimeoutChecker(*m_exec->globalData().timeoutChecker); + //TimeoutChecker localTimeoutChecker(*m_exec->globalData().timeoutChecker); + TimeoutChecker localTimeoutChecker; + localTimeoutChecker.copyTimeoutValues(m_exec->globalData().timeoutChecker); localTimeoutChecker.reset(); unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck(); do { @@ -574,18 +610,17 @@ const ClassInfo JSONObject::info = { "JSON", 0, 0, ExecState::jsonTable }; bool JSONObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - const HashEntry* entry = ExecState::jsonTable(exec)->entry(exec, propertyName); - if (!entry) - return JSObject::getOwnPropertySlot(exec, propertyName, slot); + return getStaticFunctionSlot<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, slot); +} - ASSERT(entry->attributes() & Function); - setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); - return true; +bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticFunctionDescriptor<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, descriptor); } -void JSONObject::markStringifiers(Stringifier* stringifier) +void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier) { - stringifier->mark(); + stringifier->markAggregate(markStack); } class Walker { @@ -599,11 +634,11 @@ public: } JSValue walk(JSValue unfiltered); private: - JSValue callReviver(JSValue property, JSValue unfiltered) + JSValue callReviver(JSObject* thisObj, JSValue property, JSValue unfiltered) { JSValue args[] = { property, unfiltered }; ArgList argList(args, 2); - return call(m_exec, m_function, m_callType, m_callData, jsNull(), argList); + return call(m_exec, m_function, m_callType, m_callData, thisObj, argList); } friend class Holder; @@ -613,7 +648,10 @@ private: CallType m_callType; CallData m_callData; }; - + +// We clamp recursion well beyond anything reasonable, but we also have a timeout check +// to guard against "infinite" execution by inserting arbitrarily large objects. +static const unsigned maximumFilterRecursion = 40000; enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember }; NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) @@ -627,12 +665,22 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) WalkerState state = StateUnknown; JSValue inValue = unfiltered; JSValue outValue = jsNull(); + + TimeoutChecker localTimeoutChecker; + localTimeoutChecker.copyTimeoutValues(m_exec->globalData().timeoutChecker); + localTimeoutChecker.reset(); + unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck(); while (1) { switch (state) { arrayStartState: case ArrayStartState: { ASSERT(inValue.isObject()); - ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue))); + ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue)) || asObject(inValue)->inherits(&JSArray::info)); + if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) { + m_exec->setException(createStackOverflowError(m_exec)); + return jsUndefined(); + } + JSArray* array = asArray(inValue); arrayStack.append(array); indexStack.append(0); @@ -640,6 +688,14 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) } arrayStartVisitMember: case ArrayStartVisitMember: { + if (!--tickCount) { + if (localTimeoutChecker.didTimeOut(m_exec)) { + m_exec->setException(createInterruptedExecutionException(&m_exec->globalData())); + return jsUndefined(); + } + tickCount = localTimeoutChecker.ticksUntilNextCheck(); + } + JSArray* array = arrayStack.last(); uint32_t index = indexStack.last(); if (index == array->length()) { @@ -648,7 +704,16 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) indexStack.removeLast(); break; } - inValue = array->getIndex(index); + if (isJSArray(&m_exec->globalData(), array) && array->canGetIndex(index)) + inValue = array->getIndex(index); + else { + PropertySlot slot; + if (array->getOwnPropertySlot(m_exec, index, slot)) + inValue = slot.getValue(m_exec, index); + else + inValue = jsUndefined(); + } + if (inValue.isObject()) { stateStack.append(ArrayEndVisitMember); goto stateUnknown; @@ -658,7 +723,15 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) } case ArrayEndVisitMember: { JSArray* array = arrayStack.last(); - array->setIndex(indexStack.last(), callReviver(jsString(m_exec, UString::from(indexStack.last())), outValue)); + JSValue filteredValue = callReviver(array, jsString(m_exec, UString::from(indexStack.last())), outValue); + if (filteredValue.isUndefined()) + array->deleteProperty(m_exec, indexStack.last()); + else { + if (isJSArray(&m_exec->globalData(), array) && array->canSetIndex(indexStack.last())) + array->setIndex(indexStack.last(), filteredValue); + else + array->put(m_exec, indexStack.last(), filteredValue); + } if (m_exec->hadException()) return jsNull(); indexStack.last()++; @@ -667,7 +740,12 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) objectStartState: case ObjectStartState: { ASSERT(inValue.isObject()); - ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue))); + ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue)) && !asObject(inValue)->inherits(&JSArray::info)); + if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) { + m_exec->setException(createStackOverflowError(m_exec)); + return jsUndefined(); + } + JSObject* object = asObject(inValue); objectStack.append(object); indexStack.append(0); @@ -677,6 +755,14 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) } objectStartVisitMember: case ObjectStartVisitMember: { + if (!--tickCount) { + if (localTimeoutChecker.didTimeOut(m_exec)) { + m_exec->setException(createInterruptedExecutionException(&m_exec->globalData())); + return jsUndefined(); + } + tickCount = localTimeoutChecker.ticksUntilNextCheck(); + } + JSObject* object = objectStack.last(); uint32_t index = indexStack.last(); PropertyNameArray& properties = propertyStack.last(); @@ -688,9 +774,15 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) break; } PropertySlot slot; - object->getOwnPropertySlot(m_exec, properties[index], slot); - inValue = slot.getValue(m_exec, properties[index]); - ASSERT(!m_exec->hadException()); + if (object->getOwnPropertySlot(m_exec, properties[index], slot)) + inValue = slot.getValue(m_exec, properties[index]); + else + inValue = jsUndefined(); + + // The holder may be modified by the reviver function so any lookup may throw + if (m_exec->hadException()) + return jsNull(); + if (inValue.isObject()) { stateStack.append(ObjectEndVisitMember); goto stateUnknown; @@ -702,7 +794,11 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) JSObject* object = objectStack.last(); Identifier prop = propertyStack.last()[indexStack.last()]; PutPropertySlot slot; - object->put(m_exec, prop, callReviver(jsString(m_exec, prop.ustring()), outValue), slot); + JSValue filteredValue = callReviver(object, jsString(m_exec, prop.ustring()), outValue); + if (filteredValue.isUndefined()) + object->deleteProperty(m_exec, prop); + else + object->put(m_exec, prop, filteredValue, slot); if (m_exec->hadException()) return jsNull(); indexStack.last()++; @@ -714,16 +810,29 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) outValue = inValue; break; } - if (isJSArray(&m_exec->globalData(), asObject(inValue))) + JSObject* object = asObject(inValue); + if (isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::info)) goto arrayStartState; goto objectStartState; } if (stateStack.isEmpty()) break; + state = stateStack.last(); stateStack.removeLast(); + + if (!--tickCount) { + if (localTimeoutChecker.didTimeOut(m_exec)) { + m_exec->setException(createInterruptedExecutionException(&m_exec->globalData())); + return jsUndefined(); + } + tickCount = localTimeoutChecker.ticksUntilNextCheck(); + } } - return callReviver(jsEmptyString(m_exec), outValue); + JSObject* finalHolder = constructEmptyObject(m_exec); + PutPropertySlot slot; + finalHolder->put(m_exec, m_exec->globalData().propertyNames->emptyIdentifier, outValue, slot); + return callReviver(finalHolder, jsEmptyString(m_exec), outValue); } // ECMA-262 v5 15.12.2 diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h index 8d5364a..0705a69 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h @@ -41,13 +41,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); } - static void markStringifiers(Stringifier*); + static void markStringifiers(MarkStack&, Stringifier*); private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp index ded842d..d7f5344 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Eric Seidel (eric@webkit.org) * * This library is free software; you can redistribute it and/or @@ -30,6 +30,7 @@ #include "JSGlobalObject.h" #include "NativeErrorConstructor.h" #include "ObjectPrototype.h" +#include "PropertyDescriptor.h" #include "PropertyNameArray.h" #include "Lookup.h" #include "Nodes.h" @@ -37,48 +38,22 @@ #include <math.h> #include <wtf/Assertions.h> -#define JSOBJECT_MARK_TRACING 0 - -#if JSOBJECT_MARK_TRACING - -#define JSOBJECT_MARK_BEGIN() \ - static int markStackDepth = 0; \ - for (int i = 0; i < markStackDepth; i++) \ - putchar('-'); \ - printf("%s (%p)\n", className().UTF8String().c_str(), this); \ - markStackDepth++; \ - -#define JSOBJECT_MARK_END() \ - markStackDepth--; - -#else // JSOBJECT_MARK_TRACING - -#define JSOBJECT_MARK_BEGIN() -#define JSOBJECT_MARK_END() - -#endif // JSOBJECT_MARK_TRACING - namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSObject); -void JSObject::mark() +void JSObject::markChildren(MarkStack& markStack) { - JSOBJECT_MARK_BEGIN(); - - JSCell::mark(); - m_structure->mark(); +#ifndef NDEBUG + bool wasCheckingForDefaultMarkViolation = markStack.m_isCheckingForDefaultMarkViolation; + markStack.m_isCheckingForDefaultMarkViolation = false; +#endif - PropertyStorage storage = propertyStorage(); + markChildrenDirect(markStack); - size_t storageSize = m_structure->propertyStorageSize(); - for (size_t i = 0; i < storageSize; ++i) { - JSValue v = JSValue::decode(storage[i]); - if (!v.marked()) - v.mark(); - } - - JSOBJECT_MARK_END(); +#ifndef NDEBUG + markStack.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; +#endif } UString JSObject::className() const @@ -300,7 +275,7 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi return 0; } -void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { JSValue object = getDirect(propertyName); if (object && object.isGetterSetter()) { @@ -310,8 +285,8 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO } PutPropertySlot slot; - GetterSetter* getterSetter = new (exec) GetterSetter; - putDirectInternal(exec->globalData(), propertyName, getterSetter, Getter, true, slot); + GetterSetter* getterSetter = new (exec) GetterSetter(exec); + putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, true, slot); // putDirect will change our Structure if we add a new property. For // getters and setters, though, we also need to change our Structure @@ -327,7 +302,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO getterSetter->setGetter(getterFunction); } -void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { JSValue object = getDirect(propertyName); if (object && object.isGetterSetter()) { @@ -337,8 +312,8 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO } PutPropertySlot slot; - GetterSetter* getterSetter = new (exec) GetterSetter; - putDirectInternal(exec->globalData(), propertyName, getterSetter, Setter, true, slot); + GetterSetter* getterSetter = new (exec) GetterSetter(exec); + putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot); // putDirect will change our Structure if we add a new property. For // getters and setters, though, we also need to change our Structure @@ -447,9 +422,14 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa return false; } -void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +{ + m_structure->getEnumerablePropertyNames(exec, propertyNames, this); +} + +void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { - m_structure->getPropertyNames(exec, propertyNames, this, listedAttributes); + m_structure->getOwnPropertyNames(exec, propertyNames, this, includeNonEnumerable); } bool JSObject::toBoolean(ExecState*) const @@ -491,7 +471,7 @@ JSObject* JSObject::unwrappedObject() void JSObject::removeDirect(const Identifier& propertyName) { size_t offset; - if (m_structure->isDictionary()) { + if (m_structure->isUncacheableDictionary()) { offset = m_structure->removePropertyWithoutTransition(propertyName); if (offset != WTF::notFound) putDirectOffset(offset, jsUndefined()); @@ -543,4 +523,154 @@ JSObject* constructEmptyObject(ExecState* exec) return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure()); } +bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + unsigned attributes = 0; + JSCell* cell = 0; + size_t offset = m_structure->get(propertyName, attributes, cell); + if (offset == WTF::notFound) + return false; + descriptor.setDescriptor(getDirectOffset(offset), attributes); + return true; +} + +bool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + JSObject* object = this; + while (true) { + if (object->getOwnPropertyDescriptor(exec, propertyName, descriptor)) + return true; + JSValue prototype = object->prototype(); + if (!prototype.isObject()) + return false; + object = asObject(prototype); + } +} + +static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, JSValue oldValue) +{ + if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) { + target->putWithAttributes(exec, propertyName, descriptor.value() ? descriptor.value() : oldValue, attributes & ~(Getter | Setter)); + return true; + } + attributes &= ~ReadOnly; + if (descriptor.getter() && descriptor.getter().isObject()) + target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes); + if (exec->hadException()) + return false; + if (descriptor.setter() && descriptor.setter().isObject()) + target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes); + return !exec->hadException(); +} + +bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) +{ + // If we have a new property we can just put it on normally + PropertyDescriptor current; + if (!getOwnPropertyDescriptor(exec, propertyName, current)) + return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), jsUndefined()); + + if (descriptor.isEmpty()) + return true; + + if (current.equalTo(descriptor)) + return true; + + // Filter out invalid changes + if (!current.configurable()) { + if (descriptor.configurable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to configurable attribute of unconfigurable property."); + return false; + } + if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change enumerable attribute of unconfigurable property."); + return false; + } + } + + // A generic descriptor is simply changing the attributes of an existing property + if (descriptor.isGenericDescriptor()) { + if (!current.attributesEqual(descriptor)) { + deleteProperty(exec, propertyName); + putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); + } + return true; + } + + // Changing between a normal property or an accessor property + if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { + if (!current.configurable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change access mechanism for an unconfigurable property."); + return false; + } + deleteProperty(exec, propertyName); + return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value() ? current.value() : jsUndefined()); + } + + // Changing the value and attributes of an existing property + if (descriptor.isDataDescriptor()) { + if (!current.configurable()) { + if (!current.writable() && descriptor.writable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change writable attribute of unconfigurable property."); + return false; + } + if (!current.writable()) { + if (descriptor.value() || !JSValue::strictEqual(current.value(), descriptor.value())) { + if (throwException) + throwError(exec, TypeError, "Attempting to change value of a readonly property."); + return false; + } + } + } else if (current.attributesEqual(descriptor)) { + if (!descriptor.value()) + return true; + PutPropertySlot slot; + put(exec, propertyName, descriptor.value(), slot); + if (exec->hadException()) + return false; + return true; + } + deleteProperty(exec, propertyName); + return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); + } + + // Changing the accessor functions of an existing accessor property + ASSERT(descriptor.isAccessorDescriptor()); + if (!current.configurable()) { + if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(current.setter(), descriptor.setter()))) { + if (throwException) + throwError(exec, TypeError, "Attempting to change the setter of an unconfigurable property."); + return false; + } + if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(current.getter(), descriptor.getter()))) { + if (throwException) + throwError(exec, TypeError, "Attempting to change the getter of an unconfigurable property."); + return false; + } + } + JSValue accessor = getDirect(propertyName); + if (!accessor) + return false; + GetterSetter* getterSetter = asGetterSetter(accessor); + if (current.attributesEqual(descriptor)) { + if (descriptor.setter()) + getterSetter->setSetter(asObject(descriptor.setter())); + if (descriptor.getter()) + getterSetter->setGetter(asObject(descriptor.getter())); + return true; + } + deleteProperty(exec, propertyName); + unsigned attrs = current.attributesWithOverride(descriptor); + if (descriptor.setter()) + attrs |= Setter; + if (descriptor.getter()) + attrs |= Getter; + putDirect(propertyName, getterSetter, attrs); + return true; +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h index 35f7832..9eb4e3e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,12 +27,15 @@ #include "ClassInfo.h" #include "CommonIdentifiers.h" #include "CallFrame.h" +#include "JSCell.h" #include "JSNumberCell.h" +#include "MarkStack.h" #include "PropertySlot.h" #include "PutPropertySlot.h" #include "ScopeChain.h" #include "Structure.h" #include "JSGlobalData.h" +#include <wtf/StdLibExtras.h> namespace JSC { @@ -42,11 +45,12 @@ namespace JSC { return value.asCell(); return 0; } - + + class HashEntry; class InternalFunction; + class PropertyDescriptor; class PropertyNameArray; class Structure; - struct HashEntry; struct HashTable; // ECMA 262-3 8.6.1 @@ -72,14 +76,13 @@ namespace JSC { public: explicit JSObject(PassRefPtr<Structure>); - virtual void mark(); + virtual void markChildren(MarkStack&); + ALWAYS_INLINE void markChildrenDirect(MarkStack& markStack); // The inline virtual destructor cannot be the first virtual function declared // in the class as it results in the vtable being generated as a weak symbol virtual ~JSObject(); - bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); } - JSValue prototype() const; void setPrototype(JSValue prototype); @@ -93,9 +96,11 @@ namespace JSC { bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + bool getPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&); virtual void put(ExecState*, unsigned propertyName, JSValue value); @@ -116,7 +121,9 @@ namespace JSC { virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + + virtual void getPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); @@ -179,16 +186,18 @@ namespace JSC { void fillGetterPropertySlot(PropertySlot&, JSValue* location); - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0); virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); + virtual bool defineOwnProperty(ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow); virtual bool isGlobalObject() const { return false; } virtual bool isVariableObject() const { return false; } virtual bool isActivationObject() const { return false; } virtual bool isWatchdogException() const { return false; } virtual bool isNotAnObjectErrorStub() const { return false; } + #ifdef QT_BUILD_SCRIPT_LIB virtual bool compareToObject(ExecState*, JSObject *other) { return other == this; } #endif @@ -197,15 +206,38 @@ namespace JSC { void allocatePropertyStorageInline(size_t oldSize, size_t newSize); bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } - static const size_t inlineStorageCapacity = 3; + static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; static const size_t nonInlineBaseStorageCapacity = 16; static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot)); + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + } + + protected: + void addAnonymousSlots(unsigned count); + void putAnonymousValue(unsigned index, JSValue value) + { + *locationForOffset(index) = value; + } + JSValue getAnonymousValue(unsigned index) + { + return *locationForOffset(index); } private: + // Nobody should ever ask any of these questions on something already known to be a JSObject. + using JSCell::isAPIValueWrapper; + using JSCell::isGetterSetter; + using JSCell::toObject; + void getObject(); + void getString(); + void isObject(); + void isString(); +#if USE(JSVALUE32) + void isNumber(); +#endif + ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); } PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); } @@ -228,22 +260,25 @@ namespace JSC { const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const; Structure* createInheritorID(); - RefPtr<Structure> m_inheritorID; - union { PropertyStorage m_externalStorage; EncodedJSValue m_inlineStorage[inlineStorageCapacity]; }; - }; - JSObject* asObject(JSValue); + RefPtr<Structure> m_inheritorID; + }; + +JSObject* constructEmptyObject(ExecState*); - JSObject* constructEmptyObject(ExecState*); +inline JSObject* asObject(JSCell* cell) +{ + ASSERT(cell->isObject()); + return static_cast<JSObject*>(cell); +} inline JSObject* asObject(JSValue value) { - ASSERT(asCell(value)->isObject()); - return static_cast<JSObject*>(asCell(value)); + return asObject(value.asCell()); } inline JSObject::JSObject(PassRefPtr<Structure> structure) @@ -253,6 +288,9 @@ inline JSObject::JSObject(PassRefPtr<Structure> structure) ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity); ASSERT(m_structure->isEmpty()); ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype())); +#if USE(JSVALUE64) || USE(JSVALUE32_64) + ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0); +#endif } inline JSObject::~JSObject() @@ -293,7 +331,7 @@ inline bool Structure::isUsingInlineStorage() const return (propertyStorageCapacity() == JSObject::inlineStorageCapacity); } -inline bool JSCell::isObject(const ClassInfo* info) const +inline bool JSCell::inherits(const ClassInfo* info) const { for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) { if (ci == info) @@ -302,10 +340,10 @@ inline bool JSCell::isObject(const ClassInfo* info) const return false; } -// this method is here to be after the inline declaration of JSCell::isObject -inline bool JSValue::isObject(const ClassInfo* classInfo) const +// this method is here to be after the inline declaration of JSCell::inherits +inline bool JSValue::inherits(const ClassInfo* classInfo) const { - return isCell() && asCell()->isObject(classInfo); + return isCell() && asCell()->inherits(classInfo); } ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -454,7 +492,18 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue return; } + // If we have a specific function, we may have got to this point if there is + // already a transition with the correct property name and attributes, but + // specialized to a different function. In this case we just want to give up + // and despecialize the transition. + // In this case we clear the value of specificFunction which will result + // in us adding a non-specific transition, and any subsequent lookup in + // Structure::addPropertyTransitionToExistingStructure will just use that. + if (specificFunction && m_structure->hasTransition(propertyName, attributes)) + specificFunction = 0; + RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset); + if (currentCapacity != structure->propertyStorageCapacity()) allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); @@ -480,6 +529,17 @@ inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value)); } +inline void JSObject::addAnonymousSlots(unsigned count) +{ + size_t currentCapacity = m_structure->propertyStorageCapacity(); + RefPtr<Structure> structure = Structure::addAnonymousSlotsTransition(m_structure, count); + + if (currentCapacity != structure->propertyStorageCapacity()) + allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); + + setStructure(structure.release()); +} + inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) { ASSERT(value); @@ -544,7 +604,7 @@ inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName) con inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const { if (UNLIKELY(!isCell())) { - JSObject* prototype = JSImmediate::prototype(asValue(), exec); + JSObject* prototype = synthesizePrototype(exec); if (propertyName == exec->propertyNames().underscoreProto) return prototype; if (!prototype->getPropertySlot(exec, propertyName, slot)) @@ -555,8 +615,7 @@ inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, Pro while (true) { if (cell->fastGetOwnPropertySlot(exec, propertyName, slot)) return slot.getValue(exec, propertyName); - ASSERT(cell->isObject()); - JSValue prototype = static_cast<JSObject*>(cell)->prototype(); + JSValue prototype = asObject(cell)->prototype(); if (!prototype.isObject()) return jsUndefined(); cell = asObject(prototype); @@ -572,7 +631,7 @@ inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const { if (UNLIKELY(!isCell())) { - JSObject* prototype = JSImmediate::prototype(asValue(), exec); + JSObject* prototype = synthesizePrototype(exec); if (!prototype->getPropertySlot(exec, propertyName, slot)) return jsUndefined(); return slot.getValue(exec, propertyName); @@ -581,8 +640,7 @@ inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot while (true) { if (cell->getOwnPropertySlot(exec, propertyName, slot)) return slot.getValue(exec, propertyName); - ASSERT(cell->isObject()); - JSValue prototype = static_cast<JSObject*>(cell)->prototype(); + JSValue prototype = asObject(cell)->prototype(); if (!prototype.isObject()) return jsUndefined(); cell = prototype.asCell(); @@ -592,7 +650,7 @@ inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { if (UNLIKELY(!isCell())) { - JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot); + synthesizeObject(exec)->put(exec, propertyName, value, slot); return; } asCell()->put(exec, propertyName, value, slot); @@ -601,7 +659,7 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value) { if (UNLIKELY(!isCell())) { - JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value); + synthesizeObject(exec)->put(exec, propertyName, value); return; } asCell()->put(exec, propertyName, value); @@ -627,6 +685,17 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_ m_externalStorage = newPropertyStorage; } +ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) +{ + JSCell::markChildren(markStack); + + m_structure->markAggregate(markStack); + + PropertyStorage storage = propertyStorage(); + size_t storageSize = m_structure->propertyStorageSize(); + markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize); +} + } // namespace JSC #endif // JSObject_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index 8c7b53d..e08a3d9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -37,47 +37,11 @@ JSPropertyNameIterator::~JSPropertyNameIterator() { } -JSValue JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const +void JSPropertyNameIterator::markChildren(MarkStack& markStack) { - ASSERT_NOT_REACHED(); - return JSValue(); -} - -bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue&) -{ - ASSERT_NOT_REACHED(); - return false; -} - -bool JSPropertyNameIterator::toBoolean(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return false; -} - -double JSPropertyNameIterator::toNumber(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return 0; -} - -UString JSPropertyNameIterator::toString(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return ""; -} - -JSObject* JSPropertyNameIterator::toObject(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return 0; -} - -void JSPropertyNameIterator::mark() -{ - JSCell::mark(); - if (m_object && !m_object->marked()) - m_object->mark(); + JSCell::markChildren(markStack); + if (m_object) + markStack.append(m_object); } void JSPropertyNameIterator::invalidate() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h index 9817c07..d2849a8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -44,21 +44,18 @@ namespace JSC { virtual ~JSPropertyNameIterator(); - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; - virtual bool getPrimitiveNumber(ExecState*, double&, JSValue&); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - - virtual void mark(); + virtual void markChildren(MarkStack&); JSValue next(ExecState*); void invalidate(); - + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(CompoundType)); + } private: - JSPropertyNameIterator(); - JSPropertyNameIterator(JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); + JSPropertyNameIterator(ExecState*); + JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); JSObject* m_object; RefPtr<PropertyNameArrayData> m_data; @@ -66,16 +63,16 @@ namespace JSC { PropertyNameArrayData::const_iterator m_end; }; -inline JSPropertyNameIterator::JSPropertyNameIterator() - : JSCell(0) +inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec) + : JSCell(exec->globalData().propertyNameIteratorStructure.get()) , m_object(0) , m_position(0) , m_end(0) { } -inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData) - : JSCell(0) +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()) @@ -86,12 +83,12 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefP inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v) { if (v.isUndefinedOrNull()) - return new (exec) JSPropertyNameIterator; + return new (exec) JSPropertyNameIterator(exec); JSObject* o = v.toObject(exec); PropertyNameArray propertyNames(exec); o->getPropertyNames(exec, propertyNames); - return new (exec) JSPropertyNameIterator(o, propertyNames.releaseData()); + return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData()); } inline JSValue JSPropertyNameIterator::next(ExecState* exec) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp index 85907c8..a877ec6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 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 @@ -31,12 +31,10 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject); -void JSStaticScopeObject::mark() +void JSStaticScopeObject::markChildren(MarkStack& markStack) { - JSVariableObject::mark(); - - if (!d()->registerStore.marked()) - d()->registerStore.mark(); + JSVariableObject::markChildren(markStack); + markStack.append(d()->registerStore.jsValue()); } JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h index 2caf540..5eb0e4b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 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 @@ -50,7 +50,7 @@ namespace JSC{ symbolTable().add(ident.ustring().rep(), SymbolTableEntry(-1, attributes)); } virtual ~JSStaticScopeObject(); - virtual void mark(); + virtual void markChildren(MarkStack&); bool isDynamicScope() const; virtual JSObject* toThisObject(ExecState*) const; virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp index e1fc66d..a30f729 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp @@ -103,6 +103,33 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam return true; } +bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + if (propertyName == exec->propertyNames().length) { + descriptor.setDescriptor(jsNumber(exec, m_value.size()), DontEnum | DontDelete | ReadOnly); + return true; + } + + bool isStrictUInt32; + unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); + if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) { + descriptor.setDescriptor(jsSingleCharacterSubstring(exec, m_value, i), DontDelete | ReadOnly); + return true; + } + + return false; +} + +bool JSString::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + if (getStringPropertyDescriptor(exec, propertyName, descriptor)) + return true; + if (propertyName != exec->propertyNames().underscoreProto) + return false; + descriptor.setDescriptor(exec->lexicalGlobalObject()->stringPrototype(), DontEnum); + return true; +} + bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { // The semantics here are really getPropertySlot, not getOwnPropertySlot. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h index 6db9322..eeada2e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h @@ -23,10 +23,11 @@ #ifndef JSString_h #define JSString_h -#include "CommonIdentifiers.h" #include "CallFrame.h" +#include "CommonIdentifiers.h" #include "Identifier.h" #include "JSNumberCell.h" +#include "PropertyDescriptor.h" #include "PropertySlot.h" namespace JSC { @@ -60,7 +61,7 @@ namespace JSC { class JSString : public JSCell { friend class JIT; - friend class VPtrSet; + friend struct VPtrSet; public: JSString(JSGlobalData* globalData, const UString& value) @@ -86,13 +87,14 @@ namespace JSC { bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); bool getStringPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned&) const; 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)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); } private: enum VPtrStealingHackType { VPtrStealingHack }; @@ -115,6 +117,7 @@ namespace JSC { // Actually getPropertySlot, not getOwnPropertySlot (see JSCell). virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); UString m_value; }; @@ -210,7 +213,27 @@ namespace JSC { inline JSString* JSValue::toThisJSString(ExecState* exec) { - return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec); + return isCell() ? asCell()->toThisJSString(exec) : jsString(exec, toString(exec)); + } + + inline UString JSValue::toString(ExecState* exec) const + { + if (isString()) + return static_cast<JSString*>(asCell())->value(); + if (isInt32()) + return exec->globalData().numericStrings.add(asInt32()); + if (isDouble()) + return exec->globalData().numericStrings.add(asDouble()); + if (isTrue()) + return "true"; + if (isFalse()) + return "false"; + if (isNull()) + return "null"; + if (isUndefined()) + return "undefined"; + ASSERT(isCell()); + return asCell()->toString(exec); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h index 68f2890..882b218 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h @@ -33,8 +33,10 @@ namespace JSC { NumberType = 3, NullType = 4, StringType = 5, - ObjectType = 6, - GetterSetterType = 7 + // The CompoundType value must come before any JSType that may have children + CompoundType = 6, + ObjectType = 7, + GetterSetterType = 8 }; } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h index bea188b..279510b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h @@ -27,6 +27,9 @@ #ifndef JSTypeInfo_h #define JSTypeInfo_h +// This file would be called TypeInfo.h, but that conflicts with <typeinfo.h> +// in the STL on systems without case-sensitive file systems. + #include "JSType.h" namespace JSC { @@ -38,6 +41,8 @@ namespace JSC { 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; class TypeInfo { friend class JIT; @@ -59,7 +64,8 @@ namespace JSC { 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; } unsigned flags() const { return m_flags; } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp index 885914d..39a4093 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp @@ -23,8 +23,15 @@ #include "config.h" #include "JSValue.h" +#include "BooleanConstructor.h" +#include "BooleanPrototype.h" +#include "ExceptionHelpers.h" +#include "JSGlobalObject.h" #include "JSFunction.h" +#include "JSNotAnObject.h" +#include "NumberObject.h" #include <wtf/MathExtras.h> +#include <wtf/StringExtras.h> namespace JSC { @@ -33,19 +40,97 @@ static const double D32 = 4294967296.0; // ECMA 9.4 double JSValue::toInteger(ExecState* exec) const { - if (isInt32Fast()) - return getInt32Fast(); + if (isInt32()) + return asInt32(); double d = toNumber(exec); return isnan(d) ? 0.0 : trunc(d); } double JSValue::toIntegerPreserveNaN(ExecState* exec) const { - if (isInt32Fast()) - return getInt32Fast(); + if (isInt32()) + return asInt32(); return trunc(toNumber(exec)); } +JSObject* JSValue::toObjectSlowCase(ExecState* exec) const +{ + ASSERT(!isCell()); + + if (isInt32() || isDouble()) + return constructNumber(exec, asValue()); + if (isTrue() || isFalse()) + return constructBooleanFromImmediateBoolean(exec, asValue()); + ASSERT(isUndefinedOrNull()); + JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); + exec->setException(exception); + return new (exec) JSNotAnObject(exec, exception); +} + +JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const +{ + ASSERT(!isCell()); + + if (isInt32() || isDouble()) + return constructNumber(exec, asValue()); + if (isTrue() || isFalse()) + return constructBooleanFromImmediateBoolean(exec, asValue()); + ASSERT(isUndefinedOrNull()); + return exec->globalThisValue(); +} + +JSObject* JSValue::synthesizeObject(ExecState* exec) const +{ + ASSERT(!isCell()); + if (isNumber()) + return constructNumber(exec, asValue()); + if (isBoolean()) + return constructBooleanFromImmediateBoolean(exec, asValue()); + + JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); + exec->setException(exception); + return new (exec) JSNotAnObject(exec, exception); +} + +JSObject* JSValue::synthesizePrototype(ExecState* exec) const +{ + ASSERT(!isCell()); + if (isNumber()) + return exec->lexicalGlobalObject()->numberPrototype(); + if (isBoolean()) + return exec->lexicalGlobalObject()->booleanPrototype(); + + JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); + exec->setException(exception); + return new (exec) JSNotAnObject(exec, exception); +} + +#ifndef NDEBUG +char* JSValue::description() +{ + static const size_t size = 32; + static char description[size]; + if (isInt32()) + snprintf(description, size, "Int32: %d", asInt32()); + else if (isDouble()) + snprintf(description, size, "Double: %lf", asDouble()); + else if (isCell()) + snprintf(description, size, "Cell: %p", asCell()); + else if (isTrue()) + snprintf(description, size, "True"); + else if (isFalse()) + snprintf(description, size, "False"); + else if (isNull()) + snprintf(description, size, "Null"); + else { + ASSERT(isUndefined()); + snprintf(description, size, "Undefined"); + } + + return description; +} +#endif + int32_t toInt32SlowCase(double d, bool& ok) { ok = true; @@ -84,4 +169,9 @@ uint32_t toUInt32SlowCase(double d, bool& ok) return static_cast<uint32_t>(d32); } +NEVER_INLINE double nonInlineNaN() +{ + return std::numeric_limits<double>::quiet_NaN(); +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h index 391425c..58e74b1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,16 +20,18 @@ * */ -#include <stddef.h> // for size_t -#include <stdint.h> - #ifndef JSValue_h #define JSValue_h #include "CallData.h" #include "ConstructData.h" -#include <wtf/HashTraits.h> +#include <math.h> +#include <stddef.h> // for size_t +#include <stdint.h> #include <wtf/AlwaysInline.h> +#include <wtf/Assertions.h> +#include <wtf/HashTraits.h> +#include <wtf/MathExtras.h> namespace JSC { @@ -48,31 +50,37 @@ namespace JSC { enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString }; +#if USE(JSVALUE32_64) + typedef int64_t EncodedJSValue; +#else typedef void* EncodedJSValue; +#endif + + double nonInlineNaN(); + int32_t toInt32SlowCase(double, bool& ok); + uint32_t toUInt32SlowCase(double, bool& ok); class JSValue { friend class JSImmediate; - friend struct JSValueHashTraits; - - static JSValue makeImmediate(intptr_t value) - { - return JSValue(reinterpret_cast<JSCell*>(value)); - } + friend struct EncodedJSValueHashTraits; + friend class JIT; + friend class JITStubs; + friend class JITStubCall; - intptr_t immediateValue() - { - return reinterpret_cast<intptr_t>(m_ptr); - } - public: + static EncodedJSValue encode(JSValue value); + static JSValue decode(EncodedJSValue ptr); +#if !USE(JSVALUE32_64) + private: + static JSValue makeImmediate(intptr_t value); + intptr_t immediateValue(); + public: +#endif enum JSNullTag { JSNull }; enum JSUndefinedTag { JSUndefined }; enum JSTrueTag { JSTrue }; enum JSFalseTag { JSFalse }; - static EncodedJSValue encode(JSValue value); - static JSValue decode(EncodedJSValue ptr); - JSValue(); JSValue(JSNullTag); JSValue(JSUndefinedTag); @@ -94,20 +102,22 @@ namespace JSC { JSValue(ExecState*, long long); JSValue(ExecState*, unsigned long long); JSValue(JSGlobalData*, double); - JSValue(JSGlobalData*, char); - JSValue(JSGlobalData*, unsigned char); - JSValue(JSGlobalData*, short); - JSValue(JSGlobalData*, unsigned short); JSValue(JSGlobalData*, int); JSValue(JSGlobalData*, unsigned); - JSValue(JSGlobalData*, long); - JSValue(JSGlobalData*, unsigned long); - JSValue(JSGlobalData*, long long); - JSValue(JSGlobalData*, unsigned long long); operator bool() const; - bool operator==(const JSValue other) const; - bool operator!=(const JSValue other) const; + bool operator==(const JSValue& other) const; + bool operator!=(const JSValue& other) const; + + bool isInt32() const; + bool isUInt32() const; + bool isDouble() const; + bool isTrue() const; + bool isFalse() const; + + int32_t asInt32() const; + uint32_t asUInt32() const; + double asDouble() const; // Querying the type. bool isUndefined() const; @@ -118,7 +128,7 @@ namespace JSC { bool isString() const; bool isGetterSetter() const; bool isObject() const; - bool isObject(const ClassInfo*) const; + bool inherits(const ClassInfo*) const; // Extracting the value. bool getBoolean(bool&) const; @@ -134,8 +144,6 @@ namespace JSC { // Extracting integer values. bool getUInt32(uint32_t&) const; - bool getTruncatedInt32(int32_t&) const; - bool getTruncatedUInt32(uint32_t&) const; // Basic conversions. JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; @@ -151,38 +159,17 @@ namespace JSC { JSObject* toObject(ExecState*) const; // Integer conversions. - // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)' double toInteger(ExecState*) const; double toIntegerPreserveNaN(ExecState*) const; int32_t toInt32(ExecState*) const; int32_t toInt32(ExecState*, bool& ok) const; - bool numberToInt32(int32_t& arg); uint32_t toUInt32(ExecState*) const; uint32_t toUInt32(ExecState*, bool& ok) const; - bool numberToUInt32(uint32_t& arg); - - // Fast integer operations; these values return results where the value is trivially available - // in a convenient form, for use in optimizations. No assumptions should be made based on the - // results of these operations, for example !isInt32Fast() does not necessarily indicate the - // result of getNumber will not be 0. - bool isInt32Fast() const; - int32_t getInt32Fast() const; - bool isUInt32Fast() const; - uint32_t getUInt32Fast() const; - static JSValue makeInt32Fast(int32_t); - static bool areBothInt32Fast(JSValue, JSValue); // Floating point conversions (this is a convenience method for webcore; // signle precision float is not a representation used in JS or JSC). float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); } - // API Mangled Numbers - bool isAPIMangledNumber(); - - // Garbage collection. - void mark(); - bool marked() const; - // Object operations, with the toObject operation included. JSValue get(ExecState*, const Identifier& propertyName) const; JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const; @@ -208,22 +195,72 @@ namespace JSC { bool isCell() const; JSCell* asCell() const; +#ifndef NDEBUG + char* description(); +#endif + private: enum HashTableDeletedValueTag { HashTableDeletedValue }; JSValue(HashTableDeletedValueTag); inline const JSValue asValue() const { return *this; } + JSObject* toObjectSlowCase(ExecState*) const; + JSObject* toThisObjectSlowCase(ExecState*) const; + + enum { Int32Tag = 0xffffffff }; + enum { CellTag = 0xfffffffe }; + enum { TrueTag = 0xfffffffd }; + enum { FalseTag = 0xfffffffc }; + enum { NullTag = 0xfffffffb }; + enum { UndefinedTag = 0xfffffffa }; + enum { DeletedValueTag = 0xfffffff9 }; + + enum { LowestTag = DeletedValueTag }; + + uint32_t tag() const; + int32_t payload() const; + + JSObject* synthesizePrototype(ExecState*) const; + JSObject* synthesizeObject(ExecState*) const; + +#if USE(JSVALUE32_64) + union { + EncodedJSValue asEncodedJSValue; + double asDouble; +#if PLATFORM(BIG_ENDIAN) + struct { + int32_t tag; + int32_t payload; + } asBits; +#else + struct { + int32_t payload; + int32_t tag; + } asBits; +#endif + } u; +#else // USE(JSVALUE32_64) + JSCell* m_ptr; +#endif // USE(JSVALUE32_64) + }; - bool isDoubleNumber() const; - double getDoubleNumber() const; +#if USE(JSVALUE32_64) + typedef IntHash<EncodedJSValue> EncodedJSValueHash; - JSCell* m_ptr; + struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> { + static const bool emptyValueIsZero = false; + static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); } + static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } + static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } }; +#else + typedef PtrHash<EncodedJSValue> EncodedJSValueHash; - struct JSValueHashTraits : HashTraits<EncodedJSValue> { + struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> { static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } }; +#endif // Stand-alone helper functions. inline JSValue jsNull() @@ -301,61 +338,396 @@ namespace JSC { return JSValue(globalData, d); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, char i) + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i) { return JSValue(globalData, i); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned char i) + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i) { return JSValue(globalData, i); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i) + inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); } + inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; } + + inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); } + inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; } + + inline int32_t toInt32(double val) { - return JSValue(globalData, i); + if (!(val >= -2147483648.0 && val < 2147483648.0)) { + bool ignored; + return toInt32SlowCase(val, ignored); + } + return static_cast<int32_t>(val); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i) + inline uint32_t toUInt32(double val) { - return JSValue(globalData, i); + if (!(val >= 0.0 && val < 4294967296.0)) { + bool ignored; + return toUInt32SlowCase(val, ignored); + } + return static_cast<uint32_t>(val); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i) + ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const { - return JSValue(globalData, i); + if (isInt32()) + return asInt32(); + bool ignored; + return toInt32SlowCase(toNumber(exec), ignored); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i) + inline uint32_t JSValue::toUInt32(ExecState* exec) const { - return JSValue(globalData, i); + if (isUInt32()) + return asInt32(); + bool ignored; + return toUInt32SlowCase(toNumber(exec), ignored); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long i) + inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const { - return JSValue(globalData, i); + if (isInt32()) { + ok = true; + return asInt32(); + } + return toInt32SlowCase(toNumber(exec), ok); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long i) + inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const { - return JSValue(globalData, i); + if (isUInt32()) { + ok = true; + return asInt32(); + } + return toUInt32SlowCase(toNumber(exec), ok); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long long i) +#if USE(JSVALUE32_64) + inline JSValue jsNaN(ExecState* exec) { - return JSValue(globalData, i); + return JSValue(exec, nonInlineNaN()); } - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long long i) + // JSValue member functions. + inline EncodedJSValue JSValue::encode(JSValue value) { - return JSValue(globalData, i); + return value.u.asEncodedJSValue; } - inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); } - inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; } + inline JSValue JSValue::decode(EncodedJSValue encodedJSValue) + { + JSValue v; + v.u.asEncodedJSValue = encodedJSValue; + return v; + } - inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); } - inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; } + inline JSValue::JSValue() + { + u.asBits.tag = CellTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(JSNullTag) + { + u.asBits.tag = NullTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(JSUndefinedTag) + { + u.asBits.tag = UndefinedTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(JSTrueTag) + { + u.asBits.tag = TrueTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(JSFalseTag) + { + u.asBits.tag = FalseTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(HashTableDeletedValueTag) + { + u.asBits.tag = DeletedValueTag; + u.asBits.payload = 0; + } + + inline JSValue::JSValue(JSCell* ptr) + { + u.asBits.tag = CellTag; + u.asBits.payload = reinterpret_cast<int32_t>(ptr); + } + + inline JSValue::JSValue(const JSCell* ptr) + { + u.asBits.tag = CellTag; + u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr)); + } + + inline JSValue::operator bool() const + { + return u.asBits.payload || tag() != CellTag; + } + + inline bool JSValue::operator==(const JSValue& other) const + { + return u.asEncodedJSValue == other.u.asEncodedJSValue; + } + + inline bool JSValue::operator!=(const JSValue& other) const + { + return u.asEncodedJSValue != other.u.asEncodedJSValue; + } + + inline bool JSValue::isUndefined() const + { + return tag() == UndefinedTag; + } + + inline bool JSValue::isNull() const + { + return tag() == NullTag; + } + + inline bool JSValue::isUndefinedOrNull() const + { + return isUndefined() || isNull(); + } + + inline bool JSValue::isCell() const + { + return tag() == CellTag; + } + + inline bool JSValue::isInt32() const + { + return tag() == Int32Tag; + } + + inline bool JSValue::isUInt32() const + { + return tag() == Int32Tag && asInt32() > -1; + } + + inline bool JSValue::isDouble() const + { + return tag() < LowestTag; + } + + inline bool JSValue::isTrue() const + { + return tag() == TrueTag; + } + + inline bool JSValue::isFalse() const + { + return tag() == FalseTag; + } + + inline uint32_t JSValue::tag() const + { + return u.asBits.tag; + } + + inline int32_t JSValue::payload() const + { + return u.asBits.payload; + } + + inline int32_t JSValue::asInt32() const + { + ASSERT(isInt32()); + return u.asBits.payload; + } + + inline uint32_t JSValue::asUInt32() const + { + ASSERT(isUInt32()); + return u.asBits.payload; + } + + inline double JSValue::asDouble() const + { + ASSERT(isDouble()); + return u.asDouble; + } + + ALWAYS_INLINE JSCell* JSValue::asCell() const + { + ASSERT(isCell()); + return reinterpret_cast<JSCell*>(u.asBits.payload); + } + + inline JSValue::JSValue(ExecState* exec, double d) + { + const int32_t asInt32 = static_cast<int32_t>(d); + if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0 + u.asDouble = d; + return; + } + *this = JSValue(exec, static_cast<int32_t>(d)); + } + + inline JSValue::JSValue(ExecState* exec, char i) + { + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, unsigned char i) + { + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, short i) + { + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, unsigned short i) + { + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState*, int i) + { + u.asBits.tag = Int32Tag; + u.asBits.payload = i; + } + + inline JSValue::JSValue(ExecState* exec, unsigned i) + { + if (static_cast<int32_t>(i) < 0) { + *this = JSValue(exec, static_cast<double>(i)); + return; + } + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, long i) + { + if (static_cast<int32_t>(i) != i) { + *this = JSValue(exec, static_cast<double>(i)); + return; + } + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, unsigned long i) + { + if (static_cast<uint32_t>(i) != i) { + *this = JSValue(exec, static_cast<double>(i)); + return; + } + *this = JSValue(exec, static_cast<uint32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, long long i) + { + if (static_cast<int32_t>(i) != i) { + *this = JSValue(exec, static_cast<double>(i)); + return; + } + *this = JSValue(exec, static_cast<int32_t>(i)); + } + + inline JSValue::JSValue(ExecState* exec, unsigned long long i) + { + if (static_cast<uint32_t>(i) != i) { + *this = JSValue(exec, static_cast<double>(i)); + return; + } + *this = JSValue(exec, static_cast<uint32_t>(i)); + } + + inline JSValue::JSValue(JSGlobalData* globalData, double d) + { + const int32_t asInt32 = static_cast<int32_t>(d); + if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0 + u.asDouble = d; + return; + } + *this = JSValue(globalData, static_cast<int32_t>(d)); + } + + inline JSValue::JSValue(JSGlobalData*, int i) + { + u.asBits.tag = Int32Tag; + u.asBits.payload = i; + } + + inline JSValue::JSValue(JSGlobalData* globalData, unsigned i) + { + if (static_cast<int32_t>(i) < 0) { + *this = JSValue(globalData, static_cast<double>(i)); + return; + } + *this = JSValue(globalData, static_cast<int32_t>(i)); + } + + inline bool JSValue::isNumber() const + { + return isInt32() || isDouble(); + } + + inline bool JSValue::isBoolean() const + { + return isTrue() || isFalse(); + } + + inline bool JSValue::getBoolean(bool& v) const + { + if (isTrue()) { + v = true; + return true; + } + if (isFalse()) { + v = false; + return true; + } + + return false; + } + + inline bool JSValue::getBoolean() const + { + ASSERT(isBoolean()); + return tag() == TrueTag; + } + + inline double JSValue::uncheckedGetNumber() const + { + ASSERT(isNumber()); + return isInt32() ? asInt32() : asDouble(); + } + + ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const + { + return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec)); + } + + inline bool JSValue::getNumber(double& result) const + { + if (isInt32()) { + result = asInt32(); + return true; + } + if (isDouble()) { + result = asDouble(); + return true; + } + return false; + } + +#else // USE(JSVALUE32_64) // JSValue member functions. inline EncodedJSValue JSValue::encode(JSValue value) @@ -368,6 +740,16 @@ namespace JSC { return JSValue(reinterpret_cast<JSCell*>(ptr)); } + inline JSValue JSValue::makeImmediate(intptr_t value) + { + return JSValue(reinterpret_cast<JSCell*>(value)); + } + + inline intptr_t JSValue::immediateValue() + { + return reinterpret_cast<intptr_t>(m_ptr); + } + // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page. inline JSValue::JSValue() : m_ptr(0) @@ -395,12 +777,12 @@ namespace JSC { return m_ptr; } - inline bool JSValue::operator==(const JSValue other) const + inline bool JSValue::operator==(const JSValue& other) const { return m_ptr == other.m_ptr; } - inline bool JSValue::operator!=(const JSValue other) const + inline bool JSValue::operator!=(const JSValue& other) const { return m_ptr != other.m_ptr; } @@ -414,6 +796,7 @@ namespace JSC { { return asValue() == jsNull(); } +#endif // USE(JSVALUE32_64) } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp index 78993b6..ac193ca 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp @@ -30,6 +30,7 @@ #include "JSVariableObject.h" #include "PropertyNameArray.h" +#include "PropertyDescriptor.h" namespace JSC { @@ -41,15 +42,15 @@ bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propert return JSObject::deleteProperty(exec, propertyName, checkDontDelete); } -void JSVariableObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { SymbolTable::const_iterator end = symbolTable().end(); for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) { - if ((listedAttributes & Structure::NonEnumerable) || !(it->second.getAttributes() & DontEnum)) + if (!(it->second.getAttributes() & DontEnum) || includeNonEnumerable) propertyNames.add(Identifier(exec, it->first.get())); } - JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } bool JSVariableObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const @@ -67,4 +68,14 @@ bool JSVariableObject::isVariableObject() const return true; } +bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); + if (!entry.isNull()) { + descriptor.setDescriptor(registerAt(entry.getIndex()).jsValue(), entry.getAttributes() | DontDelete); + return true; + } + return false; +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h index 310efb1..fe92729 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h @@ -49,7 +49,7 @@ namespace JSC { virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0; virtual bool deleteProperty(ExecState*, const Identifier&, bool checkDontDelete = true); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); virtual bool isVariableObject() const; virtual bool isDynamicScope() const = 0; @@ -58,6 +58,11 @@ namespace JSC { Register& registerAt(int index) const { return d->registers[index]; } + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + } + protected: // Subclasses of JSVariableObject can subclass this struct to add data // without increasing their own size (since there's a hard limit on the @@ -89,6 +94,7 @@ namespace JSC { void setRegisters(Register* r, Register* registerArray); bool symbolTableGet(const Identifier&, PropertySlot&); + bool symbolTableGet(const Identifier&, PropertyDescriptor&); bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); bool symbolTablePut(const Identifier&, JSValue); bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp index fb57018..2c39f5c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Maks Orlovich - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2009 Apple, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,11 +26,11 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject); -void JSWrapperObject::mark() +void JSWrapperObject::markChildren(MarkStack& markStack) { - JSObject::mark(); - if (m_internalValue && !m_internalValue.marked()) - m_internalValue.mark(); + JSObject::markChildren(markStack); + if (m_internalValue) + markStack.append(m_internalValue); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h index 2a2e3c6..b56a58d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h @@ -25,7 +25,7 @@ #include "JSObject.h" namespace JSC { - + // This class is used as a base for classes such as String, // Number, Boolean and Date which are wrappers for primitive types. class JSWrapperObject : public JSObject { @@ -35,23 +35,31 @@ namespace JSC { public: JSValue internalValue() const { return m_internalValue; } void setInternalValue(JSValue); - - virtual void mark(); - + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames | HasDefaultMark)); + } + private: + virtual void markChildren(MarkStack&); + JSValue m_internalValue; }; - + inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure) : JSObject(structure) { + addAnonymousSlots(1); + putAnonymousValue(0, jsNull()); } - + inline void JSWrapperObject::setInternalValue(JSValue value) { ASSERT(value); ASSERT(!value.isObject()); m_internalValue = value; + putAnonymousValue(0, value); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp index 798013a..d242282 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp @@ -129,7 +129,8 @@ template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharact return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t'; } -template <LiteralParser::ParserMode mode> LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) +// "inline" is required here to help WINSCW compiler resolve specialized argument in templated functions. +template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) { ++m_ptr; const UChar* runStart; @@ -294,7 +295,10 @@ JSValue LiteralParser::parse(ParserState initialState) } doParseArrayStartExpression: case DoParseArrayStartExpression: { + TokenType lastToken = m_lexer.currentToken().type; if (m_lexer.next() == TokRBracket) { + if (lastToken == TokComma) + return JSValue(); m_lexer.next(); lastValue = objectStack.last(); objectStack.removeLast(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h index bceee7c..0f8072b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h @@ -89,7 +89,7 @@ namespace JSC { private: TokenType lex(LiteralParserToken&); - template <ParserMode parserMode> TokenType lexString(LiteralParserToken&); + template <ParserMode mode> TokenType lexString(LiteralParserToken&); TokenType lexNumber(LiteralParserToken&); LiteralParserToken m_currentToken; UString m_string; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h index 167f2bc..4d70689 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h @@ -51,7 +51,7 @@ namespace JSC { typedef PropertySlot::GetValueFunc GetFunction; typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue value); - class HashEntry { + class HashEntry : public FastAllocBase { public: void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2) { @@ -186,6 +186,24 @@ namespace JSC { return true; } + template <class ThisImp, class ParentImp> + inline bool getStaticPropertyDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + const HashEntry* entry = table->entry(exec, propertyName); + + if (!entry) // not found, forward to parent + return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); + + PropertySlot slot; + if (entry->attributes() & Function) + setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); + else + slot.setCustom(thisObj, entry->propertyGetter()); + + descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); + return true; + } + /** * Simplified version of getStaticPropertySlot in case there are only functions. * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing @@ -204,6 +222,27 @@ namespace JSC { setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); return true; } + + /** + * Simplified version of getStaticPropertyDescriptor in case there are only functions. + * Using this instead of getStaticPropertyDescriptor allows 'this' to avoid implementing + * a dummy getValueProperty. + */ + template <class ParentImp> + inline bool getStaticFunctionDescriptor(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor)) + return true; + + const HashEntry* entry = table->entry(exec, propertyName); + if (!entry) + return false; + + PropertySlot slot; + setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); + descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); + return true; + } /** * Simplified version of getStaticPropertySlot in case there are no functions, only "values". @@ -224,6 +263,25 @@ namespace JSC { } /** + * Simplified version of getStaticPropertyDescriptor in case there are no functions, only "values". + * Using this instead of getStaticPropertyDescriptor removes the need for a FuncImp class. + */ + template <class ThisImp, class ParentImp> + inline bool getStaticValueDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + const HashEntry* entry = table->entry(exec, propertyName); + + if (!entry) // not found, forward to parent + return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); + + ASSERT(!(entry->attributes() & Function)); + PropertySlot slot; + slot.setCustom(thisObj, entry->propertyGetter()); + descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); + return true; + } + + /** * This one is for "put". * It looks up a hash entry for the property to be set. If an entry * is found it sets the value and returns true, else it returns false. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.cpp new file mode 100644 index 0000000..a350c35 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.cpp @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#include "config.h" +#include "MarkStack.h" + +namespace JSC { + +size_t MarkStack::s_pageSize = 0; + +void MarkStack::compact() +{ + ASSERT(s_pageSize); + m_values.shrinkAllocation(s_pageSize); + m_markSets.shrinkAllocation(s_pageSize); +} + +} diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h new file mode 100644 index 0000000..5bc85fa --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h @@ -0,0 +1,187 @@ +/* + * 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 MarkStack_h +#define MarkStack_h + +#include "JSValue.h" +#include <wtf/Noncopyable.h> + +namespace JSC { + + class JSGlobalData; + class Register; + + enum MarkSetProperties { MayContainNullValues, NoNullValues }; + + class MarkStack : Noncopyable { + public: + MarkStack(void* jsArrayVPtr) + : m_jsArrayVPtr(jsArrayVPtr) +#ifndef NDEBUG + , m_isCheckingForDefaultMarkViolation(false) +#endif + { + } + + ALWAYS_INLINE void append(JSValue); + ALWAYS_INLINE void append(JSCell*); + + ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) + { + appendValues(reinterpret_cast<JSValue*>(values), count, properties); + } + + ALWAYS_INLINE void appendValues(JSValue* values, size_t count, MarkSetProperties properties = NoNullValues) + { + if (count) + m_markSets.append(MarkSet(values, values + count, properties)); + } + + inline void drain(); + void compact(); + + ~MarkStack() + { + ASSERT(m_markSets.isEmpty()); + ASSERT(m_values.isEmpty()); + } + + private: + void markChildren(JSCell*); + + struct MarkSet { + MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties) + : m_values(values) + , m_end(end) + , m_properties(properties) + { + ASSERT(values); + } + JSValue* m_values; + JSValue* m_end; + MarkSetProperties m_properties; + }; + + static void* allocateStack(size_t size); + static void releaseStack(void* addr, size_t size); + + static void initializePagesize(); + static size_t pageSize() + { + if (!s_pageSize) + initializePagesize(); + return s_pageSize; + } + + template <typename T> struct MarkStackArray { + MarkStackArray() + : m_top(0) + , m_allocated(MarkStack::pageSize()) + , m_capacity(m_allocated / sizeof(T)) + { + m_data = reinterpret_cast<T*>(allocateStack(m_allocated)); + } + + ~MarkStackArray() + { + releaseStack(m_data, m_allocated); + } + + void expand() + { + size_t oldAllocation = m_allocated; + m_allocated *= 2; + m_capacity = m_allocated / sizeof(T); + void* newData = allocateStack(m_allocated); + memcpy(newData, m_data, oldAllocation); + releaseStack(m_data, oldAllocation); + m_data = reinterpret_cast<T*>(newData); + } + + inline void append(const T& v) + { + if (m_top == m_capacity) + expand(); + m_data[m_top++] = v; + } + + inline T removeLast() + { + ASSERT(m_top); + return m_data[--m_top]; + } + + inline T& last() + { + ASSERT(m_top); + return m_data[m_top - 1]; + } + + inline bool isEmpty() + { + return m_top == 0; + } + + inline size_t size() { return m_top; } + + inline void shrinkAllocation(size_t size) + { + ASSERT(size <= m_allocated); + ASSERT(0 == (size % MarkStack::pageSize())); + if (size == m_allocated) + return; +#if PLATFORM(WIN) + // We cannot release a part of a region with VirtualFree. To get around this, + // we'll release the entire region and reallocate the size that we want. + releaseStack(m_data, m_allocated); + m_data = reinterpret_cast<T*>(allocateStack(size)); +#else + releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size); +#endif + m_allocated = size; + m_capacity = m_allocated / sizeof(T); + } + + private: + size_t m_top; + size_t m_allocated; + size_t m_capacity; + T* m_data; + }; + + void* m_jsArrayVPtr; + MarkStackArray<MarkSet> m_markSets; + MarkStackArray<JSCell*> m_values; + static size_t s_pageSize; + +#ifndef NDEBUG + public: + bool m_isCheckingForDefaultMarkViolation; +#endif + }; +} + +#endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp new file mode 100644 index 0000000..aec968e --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#include "config.h" + + +#include "MarkStack.h" + +#include <unistd.h> +#if defined (__SYMBIAN32__) +#include "wtf/FastMalloc.h" +#include <e32base.h> +#include <e32std.h> +#include <e32hal.h> +#include <hal.h> +#else +#include <sys/mman.h> +#endif + +namespace JSC { + +void MarkStack::initializePagesize() +{ +#if defined (__SYMBIAN32__) + TInt page_size; + UserHal::PageSizeInBytes(page_size); + MarkStack::s_pageSize = page_size; +#else + MarkStack::s_pageSize = getpagesize(); +#endif +} + +void* MarkStack::allocateStack(size_t size) +{ +#if defined (__SYMBIAN32__) + return fastMalloc(size); +#else + return mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +#endif +} +void MarkStack::releaseStack(void* addr, size_t size) +{ +#if defined (__SYMBIAN32__) + fastFree(addr); +#else + munmap(reinterpret_cast<char*>(addr), size); +#endif +} + +} diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp new file mode 100644 index 0000000..1fdd06a --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#include "config.h" + + +#include "MarkStack.h" + +#include "windows.h" + +namespace JSC { + +void MarkStack::initializePagesize() +{ + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + MarkStack::s_pageSize = system_info.dwPageSize; +} + +void* MarkStack::allocateStack(size_t size) +{ + return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +} +void MarkStack::releaseStack(void* addr, size_t) +{ + // According to http://msdn.microsoft.com/en-us/library/aa366892(VS.85).aspx, + // dwSize must be 0 if dwFreeType is MEM_RELEASE. + VirtualFree(addr, 0, MEM_RELEASE); +} + +} diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp index 2572bc9..36771ab 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp @@ -103,14 +103,12 @@ MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure) bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot) { - const HashEntry* entry = ExecState::mathTable(exec)->entry(exec, propertyName); - - if (!entry) - return JSObject::getOwnPropertySlot(exec, propertyName, slot); + return getStaticFunctionSlot<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot); +} - ASSERT(entry->attributes() & Function); - setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); - return true; +bool MathObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticFunctionDescriptor<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, descriptor); } // ------------------------------ Functions -------------------------------- diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h index 3557d1e..a2e065f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h @@ -30,13 +30,14 @@ namespace JSC { MathObject(ExecState*, PassRefPtr<Structure>); virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); } }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp index 2840bf0..a95106d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp @@ -68,6 +68,11 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot); } +bool NumberConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, descriptor); +} + static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&) { return jsNaN(exec); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h index b1224ec..710ac86 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h @@ -32,13 +32,14 @@ namespace JSC { NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*); virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); JSValue getValueProperty(ExecState*, int token) const; static const ClassInfo info; static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); } enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h index d354b9b..f502bee 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h @@ -30,7 +30,17 @@ namespace JSC { explicit NumberObject(PassRefPtr<Structure>); static const ClassInfo info; - +#if USE(JSVALUE32) + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames)); + } +#else + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + } +#endif private: virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumericStrings.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumericStrings.h new file mode 100644 index 0000000..c0696a4 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumericStrings.h @@ -0,0 +1,74 @@ +/* + * 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 NumericStrings_h +#define NumericStrings_h + +#include "UString.h" +#include <wtf/HashFunctions.h> + +namespace JSC { + + class NumericStrings { + public: + UString add(double d) + { + CacheEntry<double>& entry = lookup(d); + if (d == entry.key && !entry.value.isNull()) + return entry.value; + entry.key = d; + entry.value = UString::from(d); + return entry.value; + } + + UString add(int i) + { + CacheEntry<int>& entry = lookup(i); + if (i == entry.key && !entry.value.isNull()) + return entry.value; + entry.key = i; + entry.value = UString::from(i); + return entry.value; + } + + private: + static const size_t cacheSize = 64; + + template<typename T> + struct CacheEntry { + T key; + UString value; + }; + + CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } + CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; } + + CacheEntry<double> doubleCache[cacheSize]; + CacheEntry<int> intCache[cacheSize]; + }; + +} // namespace JSC + +#endif // NumericStrings_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp index cf1790f..2992f1b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -21,22 +21,41 @@ #include "config.h" #include "ObjectConstructor.h" +#include "Error.h" #include "JSFunction.h" +#include "JSArray.h" #include "JSGlobalObject.h" #include "ObjectPrototype.h" +#include "PropertyDescriptor.h" +#include "PropertyNameArray.h" +#include "PrototypeFunction.h" namespace JSC { ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor); -ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype) - : InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object")) +static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorCreate(ExecState*, JSObject*, JSValue, const ArgList&); + +ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure) +: InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object")) { // ECMA 15.2.3.1 putDirectWithoutTransition(exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly); - + // no. of arguments for constructor putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete); + + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().create, objectConstructorCreate), DontEnum); } // ECMA 15.2.2 @@ -70,4 +89,212 @@ CallType ObjectConstructor::getCallData(CallData& callData) return CallTypeHost; } +JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Requested prototype of a value that is not an object."); + return asObject(args.at(0))->prototype(); +} + +JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Requested property descriptor of a value that is not an object."); + UString propertyName = args.at(1).toString(exec); + if (exec->hadException()) + return jsNull(); + JSObject* object = asObject(args.at(0)); + PropertyDescriptor descriptor; + if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor)) + return jsUndefined(); + if (exec->hadException()) + return jsUndefined(); + + JSObject* description = constructEmptyObject(exec); + if (!descriptor.isAccessorDescriptor()) { + description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0); + description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0); + } else { + description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0); + description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0); + } + + description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0); + description->putDirect(exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0); + + return description; +} + +JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Requested keys of a value that is not an object."); + PropertyNameArray properties(exec); + asObject(args.at(0))->getOwnPropertyNames(exec, properties); + JSArray* keys = constructEmptyArray(exec); + size_t numProperties = properties.size(); + for (size_t i = 0; i < numProperties; i++) + keys->push(exec, jsOwnedString(exec, properties[i].ustring())); + return keys; +} + +// ES5 8.10.5 ToPropertyDescriptor +static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc) +{ + if (!in.isObject()) { + throwError(exec, TypeError, "Property description must be an object."); + return false; + } + JSObject* description = asObject(in); + + PropertySlot enumerableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) { + desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + PropertySlot configurableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) { + desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + JSValue value; + PropertySlot valueSlot; + if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) { + desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value)); + if (exec->hadException()) + return false; + } + + PropertySlot writableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) { + desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + PropertySlot getSlot; + if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) { + JSValue get = getSlot.getValue(exec, exec->propertyNames().get); + if (exec->hadException()) + return false; + if (!get.isUndefined()) { + CallData callData; + if (get.getCallData(callData) == CallTypeNone) { + throwError(exec, TypeError, "Getter must be a function."); + return false; + } + } else + get = JSValue(); + desc.setGetter(get); + } + + PropertySlot setSlot; + if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) { + JSValue set = setSlot.getValue(exec, exec->propertyNames().set); + if (exec->hadException()) + return false; + if (!set.isUndefined()) { + CallData callData; + if (set.getCallData(callData) == CallTypeNone) { + throwError(exec, TypeError, "Setter must be a function."); + return false; + } + } else + set = JSValue(); + + desc.setSetter(set); + } + + if (!desc.isAccessorDescriptor()) + return true; + + if (desc.value()) { + throwError(exec, TypeError, "Invalid property. 'value' present on property with getter or setter."); + return false; + } + + if (desc.writablePresent()) { + throwError(exec, TypeError, "Invalid property. 'writable' present on property with getter or setter."); + return false; + } + return true; +} + +JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Properties can only be defined on Objects."); + JSObject* O = asObject(args.at(0)); + UString propertyName = args.at(1).toString(exec); + if (exec->hadException()) + return jsNull(); + PropertyDescriptor descriptor; + if (!toPropertyDescriptor(exec, args.at(2), descriptor)) + return jsNull(); + ASSERT((descriptor.attributes() & (Getter | Setter)) || (!descriptor.isAccessorDescriptor())); + ASSERT(!exec->hadException()); + O->defineOwnProperty(exec, Identifier(exec, propertyName), descriptor, true); + return O; +} + +static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties) +{ + PropertyNameArray propertyNames(exec); + asObject(properties)->getOwnPropertyNames(exec, propertyNames); + size_t numProperties = propertyNames.size(); + Vector<PropertyDescriptor> descriptors; + MarkedArgumentBuffer markBuffer; + for (size_t i = 0; i < numProperties; i++) { + PropertySlot slot; + JSValue prop = properties->get(exec, propertyNames[i]); + if (exec->hadException()) + return jsNull(); + PropertyDescriptor descriptor; + if (!toPropertyDescriptor(exec, prop, descriptor)) + return jsNull(); + descriptors.append(descriptor); + // Ensure we mark all the values that we're accumulating + if (descriptor.isDataDescriptor() && descriptor.value()) + markBuffer.append(descriptor.value()); + if (descriptor.isAccessorDescriptor()) { + if (descriptor.getter()) + markBuffer.append(descriptor.getter()); + if (descriptor.setter()) + markBuffer.append(descriptor.setter()); + } + } + for (size_t i = 0; i < numProperties; i++) { + object->defineOwnProperty(exec, propertyNames[i], descriptors[i], true); + if (exec->hadException()) + return jsNull(); + } + return object; +} + +JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Properties can only be defined on Objects."); + if (!args.at(1).isObject()) + return throwError(exec, TypeError, "Property descriptor list must be an Object."); + return defineProperties(exec, asObject(args.at(0)), asObject(args.at(1))); +} + +JSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject() && !args.at(0).isNull()) + return throwError(exec, TypeError, "Object prototype may only be an Object or null."); + JSObject* newObject = constructEmptyObject(exec); + newObject->setPrototype(args.at(0)); + if (args.at(1).isUndefined()) + return newObject; + if (!args.at(1).isObject()) + return throwError(exec, TypeError, "Property descriptor list must be an Object."); + return defineProperties(exec, newObject, asObject(args.at(1))); +} + } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h index f8c058a..9373781 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h @@ -29,7 +29,7 @@ namespace JSC { class ObjectConstructor : public InternalFunction { public: - ObjectConstructor(ExecState*, PassRefPtr<Structure>, ObjectPrototype*); + ObjectConstructor(ExecState*, PassRefPtr<Structure>, ObjectPrototype*, Structure* prototypeFunctionStructure); private: virtual ConstructType getConstructData(ConstructData&); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp index 98e4713..fccc44a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -42,6 +42,7 @@ static JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*, JSObject* ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure) : JSObject(stucture) + , m_hasNoPropertiesWithUInt32Names(true) { putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum); @@ -57,6 +58,24 @@ ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum); } +void ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +{ + JSObject::put(exec, propertyName, value, slot); + + if (m_hasNoPropertiesWithUInt32Names) { + bool isUInt32; + propertyName.toStrictUInt32(&isUInt32); + m_hasNoPropertiesWithUInt32Names = !isUInt32; + } +} + +bool ObjectPrototype::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) +{ + if (m_hasNoPropertiesWithUInt32Names) + return false; + return JSObject::getOwnPropertySlot(exec, propertyName, slot); +} + // ------------------------------ Functions -------------------------------- // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h index 7790ae0..6dd3c28 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h @@ -28,6 +28,12 @@ namespace JSC { class ObjectPrototype : public JSObject { public: ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure); + + private: + virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); + virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + + bool m_hasNoPropertiesWithUInt32Names; }; JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h index a0caff4..21120f5 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h @@ -38,7 +38,7 @@ namespace JSC { // ECMA 11.9.3 inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2) { - if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) + if (v1.isInt32() && v2.isInt32()) return v1 == v2; return equalSlowCase(exec, v1, v2); @@ -46,8 +46,6 @@ namespace JSC { ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2) { - ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2)); - do { if (v1.isNumber() && v2.isNumber()) return v1.uncheckedGetNumber() == v2.uncheckedGetNumber(); @@ -60,29 +58,30 @@ namespace JSC { if (v1.isUndefinedOrNull()) { if (v2.isUndefinedOrNull()) return true; - if (JSImmediate::isImmediate(v2)) + if (!v2.isCell()) return false; return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined(); } if (v2.isUndefinedOrNull()) { - if (JSImmediate::isImmediate(v1)) + if (!v1.isCell()) return false; return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined(); } if (v1.isObject()) { - if (v2.isObject()) + if (v2.isObject()) { return v1 == v2 #ifdef QT_BUILD_SCRIPT_LIB || asObject(v1)->compareToObject(exec, asObject(v2)) #endif ; + } JSValue p1 = v1.toPrimitive(exec); if (exec->hadException()) return false; v1 = p1; - if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) + if (v1.isInt32() && v2.isInt32()) return v1 == v2; continue; } @@ -92,7 +91,7 @@ namespace JSC { if (exec->hadException()) return false; v2 = p2; - if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) + if (v1.isInt32() && v2.isInt32()) return v1 == v2; continue; } @@ -118,7 +117,7 @@ namespace JSC { // ECMA 11.9.3 ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(JSValue v1, JSValue v2) { - ASSERT(!JSImmediate::isEitherImmediate(v1, v2)); + ASSERT(v1.isCell() && v2.isCell()); if (v1.asCell()->isString() && v2.asCell()->isString()) return asString(v1)->value() == asString(v2)->value(); @@ -128,13 +127,13 @@ namespace JSC { inline bool JSValue::strictEqual(JSValue v1, JSValue v2) { - if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) + if (v1.isInt32() && v2.isInt32()) return v1 == v2; if (v1.isNumber() && v2.isNumber()) return v1.uncheckedGetNumber() == v2.uncheckedGetNumber(); - if (JSImmediate::isEitherImmediate(v1, v2)) + if (!v1.isCell() || !v2.isCell()) return v1 == v2; return strictEqualSlowCaseInline(v1, v2); @@ -142,8 +141,8 @@ namespace JSC { inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) { - if (JSValue::areBothInt32Fast(v1, v2)) - return v1.getInt32Fast() < v2.getInt32Fast(); + if (v1.isInt32() && v2.isInt32()) + return v1.asInt32() < v2.asInt32(); double n1; double n2; @@ -167,8 +166,8 @@ namespace JSC { inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2) { - if (JSValue::areBothInt32Fast(v1, v2)) - return v1.getInt32Fast() <= v2.getInt32Fast(); + if (v1.isInt32() && v2.isInt32()) + return v1.asInt32() <= v2.asInt32(); double n1; double n2; @@ -217,8 +216,8 @@ namespace JSC { } if (rightIsNumber & leftIsString) { - RefPtr<UString::Rep> value = v2.isInt32Fast() ? - concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) : + RefPtr<UString::Rep> value = v2.isInt32() ? + concatenate(asString(v1)->value().rep(), v2.asInt32()) : concatenate(asString(v1)->value().rep(), right); if (!value) @@ -314,20 +313,13 @@ namespace JSC { resultRep = UString::Rep::createEmptyBuffer(bufferSize); UString result(resultRep); - // Loop over the openards, writing them into the output buffer. + // Loop over the operands, writing them into the output buffer. for (unsigned i = 0; i < count; ++i) { JSValue v = strings[i].jsValue(); if (LIKELY(v.isString())) result.append(asString(v)->value()); - else if (v.isInt32Fast()) - result.appendNumeric(v.getInt32Fast()); - else { - double d; - if (v.getNumber(d)) - result.appendNumeric(d); - else - result.append(v.toString(callFrame)); - } + else + result.append(v.toString(callFrame)); } return jsString(callFrame, result); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp new file mode 100644 index 0000000..4db814f --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp @@ -0,0 +1,195 @@ +/* + * 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. + */ + + +#include "config.h" + +#include "PropertyDescriptor.h" + +#include "GetterSetter.h" +#include "JSObject.h" +#include "Operations.h" + +namespace JSC { +unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1; + +bool PropertyDescriptor::writable() const +{ + ASSERT(!isAccessorDescriptor()); + return !(m_attributes & ReadOnly); +} + +bool PropertyDescriptor::enumerable() const +{ + return !(m_attributes & DontEnum); +} + +bool PropertyDescriptor::configurable() const +{ + return !(m_attributes & DontDelete); +} + +bool PropertyDescriptor::isDataDescriptor() const +{ + return m_value || (m_seenAttributes & WritablePresent); +} + +bool PropertyDescriptor::isGenericDescriptor() const +{ + return !isAccessorDescriptor() && !isDataDescriptor(); +} + +bool PropertyDescriptor::isAccessorDescriptor() const +{ + return m_getter || m_setter; +} + +void PropertyDescriptor::setUndefined() +{ + m_value = jsUndefined(); + m_attributes = ReadOnly | DontDelete | DontEnum; +} + +JSValue PropertyDescriptor::getter() const +{ + ASSERT(isAccessorDescriptor()); + return m_getter; +} + +JSValue PropertyDescriptor::setter() const +{ + ASSERT(isAccessorDescriptor()); + return m_setter; +} + +void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) +{ + ASSERT(value); + m_attributes = attributes; + if (attributes & (Getter | Setter)) { + GetterSetter* accessor = asGetterSetter(value); + m_getter = accessor->getter(); + m_setter = accessor->setter(); + ASSERT(m_getter || m_setter); + m_seenAttributes = EnumerablePresent | ConfigurablePresent; + m_attributes &= ~ReadOnly; + } else { + m_value = value; + m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; + } +} + +void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes) +{ + ASSERT(attributes & (Getter | Setter)); + ASSERT(getter || setter); + m_attributes = attributes; + m_getter = getter; + m_setter = setter; + m_attributes &= ~ReadOnly; + m_seenAttributes = EnumerablePresent | ConfigurablePresent; +} + +void PropertyDescriptor::setWritable(bool writable) +{ + if (writable) + m_attributes &= ~ReadOnly; + else + m_attributes |= ReadOnly; + m_seenAttributes |= WritablePresent; +} + +void PropertyDescriptor::setEnumerable(bool enumerable) +{ + if (enumerable) + m_attributes &= ~DontEnum; + else + m_attributes |= DontEnum; + m_seenAttributes |= EnumerablePresent; +} + +void PropertyDescriptor::setConfigurable(bool configurable) +{ + if (configurable) + m_attributes &= ~DontDelete; + else + m_attributes |= DontDelete; + m_seenAttributes |= ConfigurablePresent; +} + +void PropertyDescriptor::setSetter(JSValue setter) +{ + m_setter = setter; + m_attributes |= Setter; + m_attributes &= ~ReadOnly; +} + +void PropertyDescriptor::setGetter(JSValue getter) +{ + m_getter = getter; + m_attributes |= Getter; + m_attributes &= ~ReadOnly; +} + +bool PropertyDescriptor::equalTo(const PropertyDescriptor& other) const +{ + if (!other.m_value == m_value || + !other.m_getter == m_getter || + !other.m_setter == m_setter) + return false; + return (!m_value || JSValue::strictEqual(other.m_value, m_value)) && + (!m_getter || JSValue::strictEqual(other.m_getter, m_getter)) && + (!m_setter || JSValue::strictEqual(other.m_setter, m_setter)) && + attributesEqual(other); +} + +bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const +{ + unsigned mismatch = other.m_attributes ^ m_attributes; + unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; + if (sharedSeen & WritablePresent && mismatch & ReadOnly) + return false; + if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) + return false; + if (sharedSeen & EnumerablePresent && mismatch & DontEnum) + return false; + return true; +} + +unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const +{ + unsigned mismatch = other.m_attributes ^ m_attributes; + unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; + unsigned newAttributes = m_attributes & defaultAttributes; + if (sharedSeen & WritablePresent && mismatch & ReadOnly) + newAttributes ^= ReadOnly; + if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) + newAttributes ^= DontDelete; + if (sharedSeen & EnumerablePresent && mismatch & DontEnum) + newAttributes ^= DontEnum; + return newAttributes; +} + +} diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h new file mode 100644 index 0000000..40bec86 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h @@ -0,0 +1,80 @@ +/* + * 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 PropertyDescriptor_h +#define PropertyDescriptor_h + +#include "JSValue.h" + +namespace JSC { + class PropertyDescriptor { + public: + PropertyDescriptor() + : m_attributes(defaultAttributes) + , m_seenAttributes(0) + { + } + bool writable() const; + bool enumerable() const; + bool configurable() const; + bool isDataDescriptor() const; + bool isGenericDescriptor() const; + bool isAccessorDescriptor() const; + unsigned attributes() const { return m_attributes; } + JSValue value() const { return m_value; } + JSValue getter() const; + JSValue setter() const; + void setUndefined(); + void setDescriptor(JSValue value, unsigned attributes); + void setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes); + void setWritable(bool); + void setEnumerable(bool); + void setConfigurable(bool); + void setValue(JSValue value) { m_value = value; } + void setSetter(JSValue); + void setGetter(JSValue); + bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); } + bool writablePresent() const { return m_seenAttributes & WritablePresent; } + bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; } + bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; } + bool setterPresent() const { return m_setter; } + bool getterPresent() const { return m_getter; } + bool equalTo(const PropertyDescriptor& other) const; + bool attributesEqual(const PropertyDescriptor& other) const; + unsigned attributesWithOverride(const PropertyDescriptor& other) const; + private: + static unsigned defaultAttributes; + bool operator==(const PropertyDescriptor&){ return false; } + enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4}; + // May be a getter/setter + JSValue m_value; + JSValue m_getter; + JSValue m_setter; + unsigned m_attributes; + unsigned m_seenAttributes; + }; +} + +#endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h index 44dc2b8..5b63f79 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h @@ -61,6 +61,7 @@ namespace JSC { unsigned size; unsigned keyCount; unsigned deletedSentinelCount; + unsigned anonymousSlotCount; unsigned lastIndexUsed; Vector<unsigned>* deletedOffsets; unsigned entryIndices[1]; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp index 36fa5d8..a0a2f48 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp @@ -23,7 +23,6 @@ #include "JSFunction.h" #include "JSGlobalObject.h" -#include "JSObject.h" namespace JSC { @@ -39,7 +38,7 @@ JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const P return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList()); ASSERT(callType == CallTypeJS); // FIXME: Can this be done more efficiently using the callData? - return static_cast<JSFunction*>(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList()); + return asFunction(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList()); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h index da0d152..15d9034 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h @@ -23,7 +23,6 @@ #include "Identifier.h" #include "JSValue.h" -#include "JSImmediate.h" #include "Register.h" #include <wtf/Assertions.h> #include <wtf/NotFound.h> @@ -39,16 +38,16 @@ namespace JSC { class PropertySlot { public: PropertySlot() - : m_offset(WTF::notFound) { clearBase(); + clearOffset(); clearValue(); } explicit PropertySlot(const JSValue base) : m_slotBase(base) - , m_offset(WTF::notFound) { + clearOffset(); clearValue(); } @@ -82,8 +81,9 @@ namespace JSC { void setValueSlot(JSValue* valueSlot) { ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; clearBase(); + clearOffset(); + m_getValue = JSC_VALUE_SLOT_MARKER; m_data.valueSlot = valueSlot; } @@ -107,8 +107,9 @@ namespace JSC { void setValue(JSValue value) { ASSERT(value); - m_getValue = JSC_VALUE_SLOT_MARKER; clearBase(); + clearOffset(); + m_getValue = JSC_VALUE_SLOT_MARKER; m_value = value; m_data.valueSlot = &m_value; } @@ -116,8 +117,9 @@ namespace JSC { void setRegisterSlot(Register* registerSlot) { ASSERT(registerSlot); - m_getValue = JSC_REGISTER_SLOT_MARKER; clearBase(); + clearOffset(); + m_getValue = JSC_REGISTER_SLOT_MARKER; m_data.registerSlot = registerSlot; } @@ -147,13 +149,11 @@ namespace JSC { void setUndefined() { - clearBase(); setValue(jsUndefined()); } JSValue slotBase() const { - ASSERT(m_slotBase); return m_slotBase; } @@ -178,6 +178,13 @@ namespace JSC { #endif } + void clearOffset() + { + // Clear offset even in release builds, in case this PropertySlot has been used before. + // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.) + m_offset = WTF::notFound; + } + unsigned index() const { return m_data.index; } private: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp index e468521..1c95175 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -23,6 +23,7 @@ #include "RegExpConstructor.h" #include "ArrayPrototype.h" +#include "Error.h" #include "JSArray.h" #include "JSFunction.h" #include "JSString.h" @@ -89,7 +90,7 @@ const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, @end */ -struct RegExpConstructorPrivate { +struct RegExpConstructorPrivate : FastAllocBase { // Global search cache / settings RegExpConstructorPrivate() : lastNumSubPatterns(0) @@ -233,6 +234,11 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot); } +bool RegExpConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, descriptor); +} + JSValue regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot) { return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1); @@ -329,7 +335,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args) JSValue arg0 = args.at(0); JSValue arg1 = args.at(1); - if (arg0.isObject(&RegExpObject::info)) { + if (arg0.inherits(&RegExpObject::info)) { if (!arg1.isUndefined()) return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); return asObject(arg0); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h index 6823f3f..4b06b51 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h @@ -36,11 +36,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); } virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); static const ClassInfo info; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h index cbba85a..c1a5a25 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h @@ -44,6 +44,13 @@ namespace JSC { return JSArray::getOwnPropertySlot(exec, propertyName, slot); } + virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + if (lazyCreationData()) + fillArrayInstance(exec); + return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot) { if (lazyCreationData()) @@ -72,11 +79,11 @@ namespace JSC { return JSArray::deleteProperty(exec, propertyName, checkDontDelete); } - virtual void getPropertyNames(ExecState* exec, PropertyNameArray& arr, unsigned listedAttributes) + virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, bool includeNonEnumerable = false) { if (lazyCreationData()) fillArrayInstance(exec); - JSArray::getPropertyNames(exec, arr, listedAttributes); + JSArray::getOwnPropertyNames(exec, arr, includeNonEnumerable); } void fillArrayInstance(ExecState*); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp index 687844e..9d9dd7d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp @@ -72,6 +72,11 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); } +bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); +} + JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot) { return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global()); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h index fac9978..67113b6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h @@ -41,6 +41,7 @@ namespace JSC { JSValue exec(ExecState*, const ArgList&); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual const ClassInfo* classInfo() const { return &info; } @@ -48,7 +49,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); } private: @@ -56,7 +57,7 @@ namespace JSC { virtual CallType getCallData(CallData&); - struct RegExpObjectData { + struct RegExpObjectData : FastAllocBase { RegExpObjectData(PassRefPtr<RegExp> regExp, double lastIndex) : regExp(regExp) , lastIndex(lastIndex) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp index e507016..4714171 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp @@ -22,6 +22,7 @@ #include "RegExpPrototype.h" #include "ArrayPrototype.h" +#include "Error.h" #include "JSArray.h" #include "JSFunction.h" #include "JSObject.h" @@ -58,28 +59,28 @@ RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structur JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&RegExpObject::info)) + if (!thisValue.inherits(&RegExpObject::info)) return throwError(exec, TypeError); return asRegExpObject(thisValue)->test(exec, args); } JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&RegExpObject::info)) + if (!thisValue.inherits(&RegExpObject::info)) return throwError(exec, TypeError); return asRegExpObject(thisValue)->exec(exec, args); } JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&RegExpObject::info)) + if (!thisValue.inherits(&RegExpObject::info)) return throwError(exec, TypeError); RefPtr<RegExp> regExp; JSValue arg0 = args.at(0); JSValue arg1 = args.at(1); - if (arg0.isObject(&RegExpObject::info)) { + if (arg0.inherits(&RegExpObject::info)) { if (!arg1.isUndefined()) return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); regExp = asRegExpObject(arg0)->regExp(); @@ -99,8 +100,8 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.isObject(&RegExpObject::info)) { - if (thisValue.isObject(&RegExpPrototype::info)) + if (!thisValue.inherits(&RegExpObject::info)) { + if (thisValue.inherits(&RegExpPrototype::info)) return jsNontrivialString(exec, "//"); return throwError(exec, TypeError); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp index 5c2edab..960c525 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp @@ -56,7 +56,7 @@ int ScopeChain::localDepth() const int scopeDepth = 0; ScopeChainIterator iter = this->begin(); ScopeChainIterator end = this->end(); - while (!(*iter)->isObject(&JSActivation::info)) { + while (!(*iter)->inherits(&JSActivation::info)) { ++iter; if (iter == end) break; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h index 17aff24..c5e16c9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,6 +28,7 @@ namespace JSC { class JSGlobalData; class JSGlobalObject; class JSObject; + class MarkStack; class ScopeChainIterator; class ScopeChainNode : public FastAllocBase { @@ -204,7 +205,7 @@ namespace JSC { JSGlobalObject* globalObject() const { return m_node->globalObject(); } - void mark() const; + void markAggregate(MarkStack&) const; // Caution: this should only be used if the codeblock this is being used // with needs a full scope chain, otherwise this returns the depth of diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h index b80b8ef..984d101 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,13 +25,10 @@ namespace JSC { - inline void ScopeChain::mark() const + inline void ScopeChain::markAggregate(MarkStack& markStack) const { - for (ScopeChainNode* n = m_node; n; n = n->next) { - JSObject* o = n->object; - if (!o->marked()) - o->mark(); - } + for (ScopeChainNode* n = m_node; n; n = n->next) + markStack.append(n->object); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp index 9d1f01a..04701cb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp @@ -82,13 +82,13 @@ SmallStrings::~SmallStrings() { } -void SmallStrings::mark() +void SmallStrings::markChildren(MarkStack& markStack) { - if (m_emptyString && !m_emptyString->marked()) - m_emptyString->mark(); + if (m_emptyString) + markStack.append(m_emptyString); for (unsigned i = 0; i < numCharactersToStore; ++i) { - if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked()) - m_singleCharacterStrings[i]->mark(); + if (m_singleCharacterStrings[i]) + markStack.append(m_singleCharacterStrings[i]); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h index f0dd8df..efecbb0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 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 @@ -33,7 +33,7 @@ namespace JSC { class JSGlobalData; class JSString; - + class MarkStack; class SmallStringsStorage; class SmallStrings : public Noncopyable { @@ -56,7 +56,7 @@ namespace JSC { UString::Rep* singleCharacterStringRep(unsigned char character); - void mark(); + void markChildren(MarkStack&); unsigned count() const; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp index 4745a98..dd1ac5d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp @@ -61,6 +61,13 @@ bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pr return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); } +bool StringObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + if (internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor)) + return true; + return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { if (propertyName == exec->propertyNames().length) @@ -79,34 +86,12 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam return JSObject::deleteProperty(exec, propertyName, checkDontDelete); } -void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes) +void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable) { int size = internalValue()->value().size(); for (int i = 0; i < size; ++i) propertyNames.add(Identifier(exec, UString::from(i))); - return JSObject::getPropertyNames(exec, propertyNames, listedAttributes); -} - -bool StringObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const -{ - if (internalValue()->getStringPropertyAttributes(exec, propertyName, attributes)) - return true; - return JSObject::getPropertyAttributes(exec, propertyName, attributes); -} - -UString StringObject::toString(ExecState*) const -{ - return internalValue()->value(); -} - -UString StringObject::toThisString(ExecState*) const -{ - return internalValue()->value(); -} - -JSString* StringObject::toThisJSString(ExecState*) -{ - return internalValue(); + return JSObject::getOwnPropertyNames(exec, propertyNames); } } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h index fdeb2c1..2f5927a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h @@ -35,11 +35,11 @@ namespace JSC { virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true); - virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype); - virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false); virtual const ClassInfo* classInfo() const { return &info; } static const JS_EXPORTDATA ClassInfo info; @@ -53,11 +53,6 @@ namespace JSC { protected: StringObject(PassRefPtr<Structure>, JSString*); - - private: - virtual UString toString(ExecState*) const; - virtual UString toThisString(ExecState*) const; - virtual JSString* toThisJSString(ExecState*); }; StringObject* asStringObject(JSValue); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index bc5c0a5..1d2e03f 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h @@ -44,7 +44,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined)); + return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark)); } virtual bool toBoolean(ExecState*) const { return false; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp index ceb6b1e..c9a32b6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp @@ -23,6 +23,8 @@ #include "StringPrototype.h" #include "CachedCall.h" +#include "Error.h" +#include "Executable.h" #include "JSArray.h" #include "JSFunction.h" #include "ObjectPrototype.h" @@ -131,6 +133,11 @@ bool StringPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prop return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, slot); } +bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, descriptor); +} + // ------------------------------ Functions -------------------------- static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) @@ -220,7 +227,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue if (callType == CallTypeNone) replacementString = replacement.toString(exec); - if (pattern.isObject(&RegExpObject::info)) { + if (pattern.inherits(&RegExpObject::info)) { RegExp* reg = asRegExpObject(pattern)->regExp(); bool global = reg->global(); @@ -365,7 +372,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValu if (thisValue.isString()) return thisValue; - if (thisValue.isObject(&StringObject::info)) + if (thisValue.inherits(&StringObject::info)) return asStringObject(thisValue)->internalValue(); return throwError(exec, TypeError); @@ -376,8 +383,8 @@ JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue UString s = thisValue.toThisString(exec); unsigned len = s.size(); JSValue a0 = args.at(0); - if (a0.isUInt32Fast()) { - uint32_t i = a0.getUInt32Fast(); + if (a0.isUInt32()) { + uint32_t i = a0.asUInt32(); if (i < len) return jsSingleCharacterSubstring(exec, s, i); return jsEmptyString(exec); @@ -393,8 +400,8 @@ JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSVa UString s = thisValue.toThisString(exec); unsigned len = s.size(); JSValue a0 = args.at(0); - if (a0.isUInt32Fast()) { - uint32_t i = a0.getUInt32Fast(); + if (a0.isUInt32()) { + uint32_t i = a0.asUInt32(); if (i < len) return jsNumber(exec, s.data()[i]); return jsNaN(exec); @@ -426,8 +433,8 @@ JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue int pos; if (a1.isUndefined()) pos = 0; - else if (a1.isUInt32Fast()) - pos = min<uint32_t>(a1.getUInt32Fast(), len); + else if (a1.isUInt32()) + pos = min<uint32_t>(a1.asUInt32(), len); else { double dpos = a1.toInteger(exec); if (dpos < 0) @@ -466,7 +473,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t UString u = s; RefPtr<RegExp> reg; RegExpObject* imp = 0; - if (a0.isObject(&RegExpObject::info)) + if (a0.inherits(&RegExpObject::info)) reg = asRegExpObject(a0)->regExp(); else { /* @@ -516,7 +523,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue UString u = s; RefPtr<RegExp> reg; - if (a0.isObject(&RegExpObject::info)) + if (a0.inherits(&RegExpObject::info)) reg = asRegExpObject(a0)->regExp(); else { /* @@ -568,7 +575,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t unsigned i = 0; int p0 = 0; unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec); - if (a0.isObject(&RegExpObject::info)) { + if (a0.inherits(&RegExpObject::info)) { RegExp* reg = asRegExpObject(a0)->regExp(); if (s.isEmpty() && reg->match(s, 0) >= 0) { // empty string matched by regexp -> empty array @@ -821,8 +828,8 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu if (a0.getUInt32(smallInteger) && smallInteger <= 9) { unsigned stringSize = s.size(); unsigned bufferSize = 22 + stringSize; - UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar))); - if (!buffer) + UChar* buffer; + if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer)) return jsUndefined(); buffer[0] = '<'; buffer[1] = 'f'; @@ -869,8 +876,8 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th unsigned linkTextSize = linkText.size(); unsigned stringSize = s.size(); unsigned bufferSize = 15 + linkTextSize + stringSize; - UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar))); - if (!buffer) + UChar* buffer; + if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer)) return jsUndefined(); buffer[0] = '<'; buffer[1] = 'a'; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h index 6f5344e..580e13d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h @@ -32,6 +32,7 @@ namespace JSC { StringPrototype(ExecState*, PassRefPtr<Structure>); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp index 38c086e..05e3d7b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -127,17 +127,14 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo) , m_propertyTable(0) , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) , m_offset(noOffset) - , m_isDictionary(false) + , m_dictionaryKind(NoneDictionaryKind) , m_isPinnedPropertyTable(false) , m_hasGetterSetterProperties(false) - , m_usingSingleTransitionSlot(true) , m_attributesInPrevious(0) { ASSERT(m_prototype); ASSERT(m_prototype.isObject() || m_prototype.isNull()); - m_transitions.singleTransition = 0; - #ifndef NDEBUG #if ENABLE(JSC_MULTIPLE_THREADS) MutexLocker protect(ignoreSetMutex); @@ -156,20 +153,16 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo) Structure::~Structure() { if (m_previous) { - if (m_previous->m_usingSingleTransitionSlot) { - m_previous->m_transitions.singleTransition = 0; - } else { - ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious)))); - m_previous->m_transitions.table->remove(make_pair<RefPtr<UString::Rep>, std::pair<unsigned,JSCell*> >(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious))); - } + if (m_nameInPrevious) + m_previous->table.remove(make_pair(RefPtr<UString::Rep>(m_nameInPrevious.get()), m_attributesInPrevious), m_specificValueInPrevious); + else + m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); + } if (m_cachedPropertyNameArrayData) m_cachedPropertyNameArrayData->setCachedStructure(0); - if (!m_usingSingleTransitionSlot) - delete m_transitions.table; - if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned i = 1; i <= entryCount; i++) { @@ -279,15 +272,25 @@ void Structure::materializePropertyMap() for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) { structure = structures[i]; + if (!structure->m_nameInPrevious) { + m_propertyTable->anonymousSlotCount += structure->m_anonymousSlotsInPrevious; + continue; + } structure->m_nameInPrevious->ref(); PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed); insertIntoPropertyMapHashTable(entry); } } -void Structure::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject, unsigned listedAttributes) +void Structure::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject, bool includeNonEnumerable) { - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary) && (listedAttributes & Prototype); + getNamesFromPropertyTable(propertyNames, includeNonEnumerable); + getNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames, includeNonEnumerable); +} + +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)) { @@ -296,15 +299,23 @@ void Structure::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNam } clearEnumerationCache(); } - bool includeNonEnumerable = false; - if (listedAttributes & NonEnumerable) - includeNonEnumerable = true; - getNamesFromPropertyTable(propertyNames, includeNonEnumerable); - getNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames, includeNonEnumerable); - if ((listedAttributes & Prototype) && m_prototype.isObject()) { + 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. - asObject(m_prototype)->getPropertyNames(exec, propertyNames); + 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) { @@ -338,7 +349,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) materializePropertyMapIfNecessary(); - ASSERT(m_isDictionary); + ASSERT(isDictionary()); ASSERT(m_propertyTable); unsigned i = rep->computedHash(); @@ -380,25 +391,13 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); - if (structure->m_usingSingleTransitionSlot) { - Structure* existingTransition = structure->m_transitions.singleTransition; - if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() - && existingTransition->m_attributesInPrevious == attributes - && existingTransition->m_specificValueInPrevious == specificValue) { - - ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset); - offset = structure->m_transitions.singleTransition->m_offset; - return existingTransition; - } - } else { - if (Structure* existingTransition = structure->m_transitions.table->get(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(propertyName.ustring().rep(), make_pair(attributes, specificValue)))) { - ASSERT(existingTransition->m_offset != noOffset); - offset = existingTransition->m_offset; - return existingTransition; - } + if (Structure* existingTransition = structure->table.get(make_pair(RefPtr<UString::Rep>(propertyName.ustring().rep()), attributes), specificValue)) { + ASSERT(existingTransition->m_offset != noOffset); + offset = existingTransition->m_offset; + return existingTransition; } return 0; @@ -406,12 +405,12 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); if (structure->transitionCount() > s_maxTransitionLength) { - RefPtr<Structure> transition = toDictionaryTransition(structure); + RefPtr<Structure> transition = toCacheableDictionaryTransition(structure); ASSERT(structure != transition); offset = transition->put(propertyName, attributes, specificValue); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) @@ -449,27 +448,15 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_offset = offset; - if (structure->m_usingSingleTransitionSlot) { - if (!structure->m_transitions.singleTransition) { - structure->m_transitions.singleTransition = transition.get(); - return transition.release(); - } - - Structure* existingTransition = structure->m_transitions.singleTransition; - structure->m_usingSingleTransitionSlot = false; - StructureTransitionTable* transitionTable = new StructureTransitionTable; - structure->m_transitions.table = transitionTable; - transitionTable->add(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(existingTransition->m_nameInPrevious.get(), make_pair(existingTransition->m_attributesInPrevious, existingTransition->m_specificValueInPrevious)), existingTransition); - } - structure->m_transitions.table->add(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(propertyName.ustring().rep(), make_pair(attributes, specificValue)), transition.get()); + structure->table.add(make_pair(RefPtr<UString::Rep>(propertyName.ustring().rep()), attributes), transition.get(), specificValue); return transition.release(); } PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isUncacheableDictionary()); - RefPtr<Structure> transition = toDictionaryTransition(structure); + RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure); offset = transition->remove(propertyName); @@ -511,6 +498,47 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur return transition.release(); } +PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structure, unsigned count) +{ + if (Structure* transition = structure->table.getAnonymousSlotTransition(count)) { + ASSERT(transition->storedPrototype() == structure->storedPrototype()); + return transition; + } + ASSERT(count); + ASSERT(count < ((1<<6) - 2)); + RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); + + transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; + transition->m_previous = structure; + transition->m_nameInPrevious = 0; + transition->m_attributesInPrevious = 0; + transition->m_anonymousSlotsInPrevious = count; + transition->m_specificValueInPrevious = 0; + transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; + transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + + if (structure->m_propertyTable) { + if (structure->m_isPinnedPropertyTable) + transition->m_propertyTable = structure->copyPropertyTable(); + else { + transition->m_propertyTable = structure->m_propertyTable; + structure->m_propertyTable = 0; + } + } else { + if (structure->m_previous) + transition->materializePropertyMap(); + else + transition->createPropertyMapHashTable(); + } + + transition->addAnonymousSlots(count); + if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) + transition->growPropertyStorageCapacity(); + + structure->table.addAnonymousSlotTransition(count, transition.get()); + return transition.release(); +} + PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) { RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo()); @@ -526,25 +554,35 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) return transition.release(); } -PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure) +PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind) { - ASSERT(!structure->m_isDictionary); - + ASSERT(!structure->isDictionary()); + RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); - transition->m_isDictionary = true; + transition->m_dictionaryKind = kind; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - + structure->materializePropertyMapIfNecessary(); transition->m_propertyTable = structure->copyPropertyTable(); transition->m_isPinnedPropertyTable = true; - + return transition.release(); } +PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure) +{ + return toDictionaryTransition(structure, CachedDictionaryKind); +} + +PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure) +{ + return toDictionaryTransition(structure, UncachedDictionaryKind); +} + PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) { - ASSERT(structure->m_isDictionary); + ASSERT(structure->isDictionary()); // Since dictionary Structures are not shared, and no opcodes specialize // for them, we don't need to allocate a new Structure when transitioning @@ -553,15 +591,13 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the // deleted offsets vector) before transitioning from dictionary. if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty()) - structure->m_isDictionary = false; + structure->m_dictionaryKind = NoneDictionaryKind; return structure; } size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { - ASSERT(!m_transitions.singleTransition); - materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; @@ -574,8 +610,7 @@ size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, u size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { - ASSERT(!m_transitions.singleTransition); - ASSERT(m_isDictionary); + ASSERT(isUncacheableDictionary()); materializePropertyMapIfNecessary(); @@ -638,6 +673,7 @@ PropertyMapHashTable* Structure::copyPropertyTable() if (m_propertyTable->deletedOffsets) newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets); + newTable->anonymousSlotCount = m_propertyTable->anonymousSlotCount; return newTable; } @@ -817,7 +853,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel newOffset = m_propertyTable->deletedOffsets->last(); m_propertyTable->deletedOffsets->removeLast(); } else - newOffset = m_propertyTable->keyCount; + newOffset = m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount; m_propertyTable->entries()[entryIndex - 1].offset = newOffset; ++m_propertyTable->keyCount; @@ -829,6 +865,16 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel return newOffset; } +void Structure::addAnonymousSlots(unsigned count) +{ + m_propertyTable->anonymousSlotCount += count; +} + +bool Structure::hasTransition(UString::Rep* rep, unsigned attributes) +{ + return table.hasTransition(make_pair(RefPtr<UString::Rep>(rep), attributes)); +} + size_t Structure::remove(const Identifier& propertyName) { ASSERT(!propertyName.isNull()); @@ -982,6 +1028,7 @@ void Structure::rehashPropertyMapHashTable(unsigned newTableSize) m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize))); m_propertyTable->size = newTableSize; m_propertyTable->sizeMask = newTableSize - 1; + m_propertyTable->anonymousSlotCount = oldTable->anonymousSlotCount; unsigned lastIndexUsed = 0; unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount; @@ -1021,8 +1068,7 @@ void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool int i = 0; unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned k = 1; k <= entryCount; k++) { - if (m_propertyTable->entries()[k].key - && (includeNonEnumerable || !(m_propertyTable->entries()[k].attributes & DontEnum))) { + if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || includeNonEnumerable)) { PropertyMapEntry* value = &m_propertyTable->entries()[k]; int j; for (j = i - 1; j >= 0 && a[j]->index > value->index; --j) @@ -1049,8 +1095,7 @@ void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool PropertyMapEntry** p = sortedEnumerables.data(); unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned i = 1; i <= entryCount; i++) { - if (m_propertyTable->entries()[i].key - && (includeNonEnumerable || !(m_propertyTable->entries()[i].attributes & DontEnum))) + if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || includeNonEnumerable)) *p++ = &m_propertyTable->entries()[i]; } @@ -1082,7 +1127,7 @@ void Structure::getNamesFromClassInfoTable(ExecState* exec, const ClassInfo* cla int hashSizeMask = table->compactSize - 1; const HashEntry* entry = table->table; for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && (includeNonEnumerable || !(entry->attributes() & DontEnum))) + if (entry->key() && (!(entry->attributes() & DontEnum) || includeNonEnumerable)) propertyNames.add(entry->key()); } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h index ca4552b..d012ba9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -44,18 +44,15 @@ namespace JSC { + class MarkStack; class PropertyNameArray; class PropertyNameArrayData; class StructureChain; class Structure : public RefCounted<Structure> { public: - enum ListedAttribute { - NonEnumerable = 1 << 1, - Prototype = 1 << 2 - }; - friend class JIT; + friend class StructureTransitionTable; static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo) { return adoptRef(new Structure(prototype, typeInfo)); @@ -70,25 +67,24 @@ namespace JSC { static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset); static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype); - static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&); + static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&); + static PassRefPtr<Structure> addAnonymousSlotsTransition(Structure*, unsigned count); static PassRefPtr<Structure> getterSetterTransition(Structure*); - static PassRefPtr<Structure> toDictionaryTransition(Structure*); + static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*); + static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*); static PassRefPtr<Structure> fromDictionaryTransition(Structure*); ~Structure(); - void mark() - { - if (!m_prototype.marked()) - m_prototype.mark(); - } + 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); void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; } - - bool isDictionary() const { return m_isDictionary; } + + bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; } + bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; } const TypeInfo& typeInfo() const { return m_typeInfo; } @@ -100,7 +96,7 @@ namespace JSC { void growPropertyStorageCapacity(); size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; } - size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } + size_t 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); @@ -108,10 +104,20 @@ namespace JSC { size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) { ASSERT(!propertyName.isNull()); - return get(propertyName._ustring.rep(), attributes, specificValue); + return get(propertyName.ustring().rep(), attributes, specificValue); + } + bool transitionedFor(const JSCell* specificValue) + { + return m_specificValueInPrevious == specificValue; + } + bool hasTransition(UString::Rep*, unsigned attributes); + bool hasTransition(const Identifier& propertyName, unsigned attributes) + { + return hasTransition(propertyName._ustring.rep(), attributes); } - void getPropertyNames(ExecState*, PropertyNameArray&, JSObject*, unsigned listedAttributes = Prototype); + void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); + void getOwnPropertyNames(ExecState*, PropertyNameArray&, JSObject*, bool includeNonEnumerable = false); bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } @@ -123,9 +129,17 @@ namespace JSC { private: Structure(JSValue prototype, const TypeInfo&); + + typedef enum { + NoneDictionaryKind = 0, + CachedDictionaryKind = 1, + UncachedDictionaryKind = 2 + } DictionaryKind; + static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind); size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); + void addAnonymousSlots(unsigned slotCount); void getNamesFromPropertyTable(PropertyNameArray&, bool includeNonEnumerable = false); void getNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&, bool includeNonEnumerable = false); @@ -171,13 +185,10 @@ namespace JSC { RefPtr<Structure> m_previous; RefPtr<UString::Rep> m_nameInPrevious; - - union { - Structure* singleTransition; - StructureTransitionTable* table; - } m_transitions; JSCell* m_specificValueInPrevious; + StructureTransitionTable table; + RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; PropertyMapHashTable* m_propertyTable; @@ -185,11 +196,18 @@ namespace JSC { size_t m_propertyStorageCapacity; signed char m_offset; - bool m_isDictionary : 1; + unsigned m_dictionaryKind : 2; bool m_isPinnedPropertyTable : 1; bool m_hasGetterSetterProperties : 1; - bool m_usingSingleTransitionSlot : 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. + // This bitfield optimization is insignificant for the Symbian emulator target. + unsigned m_attributesInPrevious; +#else unsigned m_attributesInPrevious : 7; +#endif + unsigned m_anonymousSlotsInPrevious : 6; }; inline size_t Structure::get(const Identifier& propertyName) @@ -236,7 +254,58 @@ namespace JSC { return m_propertyTable->entries()[entryIndex - 1].offset; } } + + bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue) + { + if (usingSingleTransitionSlot()) { + Structure* existingTransition = singleTransition(); + return existingTransition && existingTransition->m_nameInPrevious.get() == key.first + && existingTransition->m_attributesInPrevious == key.second + && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0); + } + TransitionTable::iterator find = table()->find(key); + if (find == table()->end()) + return false; + + return find->second.first || find->second.second->transitionedFor(specificValue); + } + Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const + { + if (usingSingleTransitionSlot()) { + Structure* existingTransition = singleTransition(); + if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first + && existingTransition->m_attributesInPrevious == key.second + && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0)) + return existingTransition; + return 0; + } + + Transition transition = table()->get(key); + if (transition.second && transition.second->transitionedFor(specificValue)) + return transition.second; + return transition.first; + } + + bool StructureTransitionTable::hasTransition(const StructureTransitionTableHash::Key& key) const + { + if (usingSingleTransitionSlot()) { + Structure* transition = singleTransition(); + return transition && transition->m_nameInPrevious == key.first + && transition->m_attributesInPrevious == key.second; + } + return table()->contains(key); + } + + void StructureTransitionTable::reifySingleTransition() + { + ASSERT(usingSingleTransitionSlot()); + Structure* existingTransition = singleTransition(); + TransitionTable* transitionTable = new TransitionTable; + setTransitionTable(transitionTable); + if (existingTransition) + add(make_pair(RefPtr<UString::Rep>(existingTransition->m_nameInPrevious.get()), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious); + } } // namespace JSC #endif // Structure_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp index acebc86..2c38b67 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp @@ -57,7 +57,10 @@ bool StructureChain::isCacheable() const uint32_t i = 0; while (m_vector[i]) { - if (m_vector[i++]->isDictionary()) + // 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; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h index 804cbeb..0fa7b73 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -30,6 +30,8 @@ #include <wtf/HashFunctions.h> #include <wtf/HashMap.h> #include <wtf/HashTraits.h> +#include <wtf/PtrAndFlags.h> +#include <wtf/OwnPtr.h> #include <wtf/RefPtr.h> namespace JSC { @@ -37,7 +39,7 @@ namespace JSC { class Structure; struct StructureTransitionTableHash { - typedef std::pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> > Key; + typedef std::pair<RefPtr<UString::Rep>, unsigned> Key; static unsigned hash(const Key& p) { return p.first->computedHash(); @@ -53,20 +55,159 @@ namespace JSC { struct StructureTransitionTableHashTraits { typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits; - typedef WTF::GenericHashTraits<unsigned> SecondFirstTraits; - typedef WTF::GenericHashTraits<JSCell*> SecondSecondTraits; - typedef std::pair<FirstTraits::TraitType, std::pair<SecondFirstTraits::TraitType, SecondSecondTraits::TraitType> > TraitType; + typedef WTF::GenericHashTraits<unsigned> SecondTraits; + typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType; - static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondFirstTraits::emptyValueIsZero && SecondSecondTraits::emptyValueIsZero; - static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), std::make_pair(SecondFirstTraits::emptyValue(), SecondSecondTraits::emptyValue())); } + static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero; + static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); } - static const bool needsDestruction = FirstTraits::needsDestruction || SecondFirstTraits::needsDestruction || SecondSecondTraits::needsDestruction; + static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction; static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); } static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); } }; - typedef HashMap<StructureTransitionTableHash::Key, Structure*, StructureTransitionTableHash, StructureTransitionTableHashTraits> StructureTransitionTable; + class StructureTransitionTable { + typedef std::pair<Structure*, Structure*> Transition; + struct TransitionTable : public HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> { + typedef HashMap<unsigned, Structure*> AnonymousSlotMap; + + void addSlotTransition(unsigned count, Structure* structure) + { + ASSERT(!getSlotTransition(count)); + if (!m_anonymousSlotTable) + m_anonymousSlotTable.set(new AnonymousSlotMap); + m_anonymousSlotTable->add(count, structure); + } + + void removeSlotTransition(unsigned count) + { + ASSERT(getSlotTransition(count)); + m_anonymousSlotTable->remove(count); + } + + Structure* getSlotTransition(unsigned count) + { + if (!m_anonymousSlotTable) + return 0; + + AnonymousSlotMap::iterator find = m_anonymousSlotTable->find(count); + if (find == m_anonymousSlotTable->end()) + return 0; + return find->second; + } + private: + OwnPtr<AnonymousSlotMap> m_anonymousSlotTable; + }; + public: + StructureTransitionTable() { + m_transitions.m_singleTransition.set(0); + m_transitions.m_singleTransition.setFlag(usingSingleSlot); + } + + ~StructureTransitionTable() { + if (!usingSingleTransitionSlot()) + delete table(); + } + + // The contains and get methods accept imprecise matches, so if an unspecialised transition exists + // for the given key they will consider that transition to be a match. If a specialised transition + // exists and it matches the provided specificValue, get will return the specific transition. + inline bool contains(const StructureTransitionTableHash::Key&, JSCell* specificValue); + inline Structure* get(const StructureTransitionTableHash::Key&, JSCell* specificValue) const; + inline bool hasTransition(const StructureTransitionTableHash::Key& key) const; + void remove(const StructureTransitionTableHash::Key& key, JSCell* specificValue) + { + if (usingSingleTransitionSlot()) { + ASSERT(contains(key, specificValue)); + setSingleTransition(0); + return; + } + TransitionTable::iterator find = table()->find(key); + if (!specificValue) + find->second.first = 0; + else + find->second.second = 0; + if (!find->second.first && !find->second.second) + table()->remove(find); + } + void add(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue) + { + if (usingSingleTransitionSlot()) { + if (!singleTransition()) { + setSingleTransition(structure); + return; + } + reifySingleTransition(); + } + if (!specificValue) { + TransitionTable::iterator find = table()->find(key); + if (find == table()->end()) + table()->add(key, Transition(structure, 0)); + else + find->second.first = structure; + } else { + // If we're adding a transition to a specific value, then there cannot be + // an existing transition + ASSERT(!table()->contains(key)); + table()->add(key, Transition(0, structure)); + } + } + + Structure* getAnonymousSlotTransition(unsigned count) + { + if (usingSingleTransitionSlot()) + return 0; + return table()->getSlotTransition(count); + } + + void addAnonymousSlotTransition(unsigned count, Structure* structure) + { + if (usingSingleTransitionSlot()) + reifySingleTransition(); + ASSERT(!table()->getSlotTransition(count)); + table()->addSlotTransition(count, structure); + } + + void removeAnonymousSlotTransition(unsigned count) + { + ASSERT(!usingSingleTransitionSlot()); + table()->removeSlotTransition(count); + } + private: + TransitionTable* table() const { ASSERT(!usingSingleTransitionSlot()); return m_transitions.m_table; } + Structure* singleTransition() const { + ASSERT(usingSingleTransitionSlot()); + return m_transitions.m_singleTransition.get(); + } + bool usingSingleTransitionSlot() const { return m_transitions.m_singleTransition.isFlagSet(usingSingleSlot); } + void setSingleTransition(Structure* structure) + { + ASSERT(usingSingleTransitionSlot()); + m_transitions.m_singleTransition.set(structure); + } + + void setTransitionTable(TransitionTable* table) + { + ASSERT(usingSingleTransitionSlot()); +#ifndef NDEBUG + setSingleTransition(0); +#endif + m_transitions.m_table = table; + // This implicitly clears the flag that indicates we're using a single transition + ASSERT(!usingSingleTransitionSlot()); + } + inline void reifySingleTransition(); + + enum UsingSingleSlot { + usingSingleSlot + }; + // Last bit indicates whether we are using the single transition optimisation + union { + TransitionTable* m_table; + PtrAndFlagsBase<Structure, UsingSingleSlot> m_singleTransition; + } m_transitions; + }; } // namespace JSC diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h index c00f95a..f5e2669 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h @@ -121,6 +121,10 @@ namespace JSC { typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable; + class SharedSymbolTable : public SymbolTable, public RefCounted<SharedSymbolTable> + { + }; + } // namespace JSC #endif // SymbolTable_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp index 045a33a..d7fca33 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp @@ -120,6 +120,13 @@ void TimeoutChecker::reset() m_timeExecuting = 0; } +void TimeoutChecker::copyTimeoutValues(TimeoutChecker* other) +{ + m_timeoutInterval = other->m_timeoutInterval; + m_startCount = other->m_startCount; + m_intervalBetweenChecks = other->m_intervalBetweenChecks; +} + bool TimeoutChecker::didTimeOut(ExecState* exec) { unsigned currentTime = getCPUTime(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h index 1680d6d..f9c86ee 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h @@ -59,6 +59,7 @@ namespace JSC { } void reset(); + void copyTimeoutValues(TimeoutChecker* other); virtual bool didTimeOut(ExecState*); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp index fa19932..e66ca93 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp @@ -32,12 +32,14 @@ #include <ctype.h> #include <float.h> #include <limits.h> +#include <limits> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> #include <wtf/MathExtras.h> +#include <wtf/StringExtras.h> #include <wtf/Vector.h> #include <wtf/unicode/UTF8.h> #include <wtf/StringExtras.h> @@ -69,20 +71,20 @@ static const int minLengthToShare = 10; static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); } static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); } -static inline UChar* allocChars(size_t length) +static inline PossiblyNull<UChar*> allocChars(size_t length) { ASSERT(length); if (length > maxUChars()) return 0; - return static_cast<UChar*>(tryFastMalloc(sizeof(UChar) * length)); + return tryFastMalloc(sizeof(UChar) * length); } -static inline UChar* reallocChars(UChar* buffer, size_t length) +static inline PossiblyNull<UChar*> reallocChars(UChar* buffer, size_t length) { ASSERT(length); if (length > maxUChars()) return 0; - return static_cast<UChar*>(tryFastRealloc(buffer, sizeof(UChar) * length)); + return tryFastRealloc(buffer, sizeof(UChar) * length); } static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) @@ -481,8 +483,7 @@ static inline bool expandCapacity(UString::Rep* rep, int requiredLength) if (requiredLength > base->capacity) { size_t newCapacity = expandedSize(requiredLength, base->preCapacity); UChar* oldBuf = base->buf; - base->buf = reallocChars(base->buf, newCapacity); - if (!base->buf) { + if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) { base->buf = oldBuf; return false; } @@ -513,8 +514,7 @@ bool UString::Rep::reserveCapacity(int capacity) size_t newCapacity = expandedSize(capacity, base->preCapacity); UChar* oldBuf = base->buf; - base->buf = reallocChars(base->buf, newCapacity); - if (!base->buf) { + if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) { base->buf = oldBuf; return false; } @@ -541,8 +541,8 @@ void UString::expandPreCapacity(int requiredPreCap) size_t newCapacity = expandedSize(requiredPreCap, base->capacity); int delta = newCapacity - base->capacity - base->preCapacity; - UChar* newBuf = allocChars(newCapacity); - if (!newBuf) { + UChar* newBuf; + if (!allocChars(newCapacity).getValue(newBuf)) { makeNull(); return; } @@ -567,8 +567,8 @@ static PassRefPtr<UString::Rep> createRep(const char* c) return &UString::Rep::empty(); size_t length = strlen(c); - UChar* d = allocChars(length); - if (!d) + UChar* d; + if (!allocChars(length).getValue(d)) return &UString::Rep::null(); else { for (size_t i = 0; i < length; i++) @@ -657,8 +657,8 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re } else { // This is shared in some way that prevents us from modifying base, so we must make a whole new string. size_t newCapacity = expandedSize(length, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) rep = &UString::Rep::null(); else { copyChars(d, rep->data(), thisSize); @@ -713,8 +713,8 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re } else { // This is shared in some way that prevents us from modifying base, so we must make a whole new string. size_t newCapacity = expandedSize(length, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) rep = &UString::Rep::null(); else { copyChars(d, rep->data(), thisSize); @@ -801,8 +801,8 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b) // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string size_t newCapacity = expandedSize(length, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) return 0; copyChars(d, a->data(), aSize); copyChars(d + aSize, b->data(), bSize); @@ -943,8 +943,7 @@ UString UString::from(int i) return UString(p, static_cast<int>(end - p)); } -#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) -UString UString::from(int64_t i) +UString UString::from(long long i) { UChar buf[1 + sizeof(i) * 3]; UChar* end = buf + sizeof(buf) / sizeof(UChar); @@ -952,9 +951,13 @@ UString UString::from(int64_t i) if (i == 0) *--p = '0'; - else if (i == LLONG_MIN) { + else if (i == std::numeric_limits<long long>::min()) { char minBuf[1 + sizeof(i) * 3]; - snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", LLONG_MIN); +#if PLATFORM(WIN_OS) + snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min()); +#else + snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min()); +#endif return UString(minBuf); } else { bool negative = false; @@ -972,7 +975,6 @@ UString UString::from(int64_t i) return UString(p, static_cast<int>(end - p)); } -#endif UString UString::from(unsigned int u) { @@ -1026,6 +1028,8 @@ UString UString::from(double d) // avoid ever printing -NaN, in JS conceptually there is only one NaN value if (isnan(d)) return "NaN"; + if (!d) + return "0"; // -0 -> "0" char buf[80]; int decimalPoint; @@ -1108,8 +1112,8 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in if (totalLength == 0) return ""; - UChar* buffer = allocChars(totalLength); - if (!buffer) + UChar* buffer; + if (!allocChars(totalLength).getValue(buffer)) return null(); int maxCount = max(rangeCount, separatorCount); @@ -1137,8 +1141,8 @@ UString UString::replaceRange(int rangeStart, int rangeLength, const UString& re if (totalLength == 0) return ""; - UChar* buffer = allocChars(totalLength); - if (!buffer) + UChar* buffer; + if (!allocChars(totalLength).getValue(buffer)) return null(); copyChars(buffer, data(), rangeStart); @@ -1185,8 +1189,8 @@ UString& UString::append(const UString &t) } else { // This is shared in some way that prevents us from modifying base, so we must make a whole new string. size_t newCapacity = expandedSize(length, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) makeNull(); else { copyChars(d, data(), thisSize); @@ -1208,18 +1212,6 @@ UString& UString::append(const UChar* tData, int tSize) return *this; } -UString& UString::appendNumeric(int i) -{ - m_rep = concatenate(rep(), i); - return *this; -} - -UString& UString::appendNumeric(double d) -{ - m_rep = concatenate(rep(), d); - return *this; -} - UString& UString::append(const char* t) { m_rep = concatenate(m_rep.release(), t); @@ -1238,8 +1230,8 @@ UString& UString::append(UChar c) if (length == 0) { // this is empty - must make a new m_rep because we don't want to pollute the shared empty one size_t newCapacity = expandedSize(1, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) makeNull(); else { d[0] = c; @@ -1266,8 +1258,8 @@ UString& UString::append(UChar c) } else { // This is shared in some way that prevents us from modifying base, so we must make a whole new string. size_t newCapacity = expandedSize(length + 1, 0); - UChar* d = allocChars(newCapacity); - if (!d) + UChar* d; + if (!allocChars(newCapacity).getValue(d)) makeNull(); else { copyChars(d, data(), length); @@ -1345,8 +1337,7 @@ UString& UString::operator=(const char* c) m_rep->_hash = 0; m_rep->len = l; } else { - d = allocChars(l); - if (!d) { + if (!allocChars(l).getValue(d)) { makeNull(); return *this; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h index ab64f52..58c3615 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h @@ -92,7 +92,8 @@ namespace JSC { { // Guard against integer overflow if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) { - if (void * buf = tryFastMalloc(size * sizeof(UChar))) + void* buf = 0; + if (tryFastMalloc(size * sizeof(UChar)).getValue(buf)) return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size)); } return adoptRef(new BaseString(0, 0, 0)); @@ -257,9 +258,7 @@ namespace JSC { } static UString from(int); -#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) - static UString from(int64_t i); -#endif + static UString from(long long); static UString from(unsigned int); static UString from(long); static UString from(double); @@ -289,8 +288,6 @@ namespace JSC { UString& append(UChar); UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); } UString& append(const UChar*, int size); - UString& appendNumeric(int); - UString& appendNumeric(double); bool getCString(CStringBuffer&) const; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp index e2e8aba..e62add3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp @@ -42,8 +42,8 @@ void Generator::generateEnter() { #if PLATFORM(X86) // On x86 edi & esi are callee preserved registers. - push(X86::edi); - push(X86::esi); + push(X86Registers::edi); + push(X86Registers::esi); #if COMPILER(MSVC) // Move the arguments into registers. @@ -72,8 +72,8 @@ void Generator::generateReturnSuccess() // Restore callee save registers. #if PLATFORM(X86) - pop(X86::esi); - pop(X86::edi); + pop(X86Registers::esi); + pop(X86Registers::edi); #endif ret(); } @@ -111,8 +111,8 @@ void Generator::generateReturnFailure() move(Imm32(-1), returnRegister); #if PLATFORM(X86) - pop(X86::esi); - pop(X86::edi); + pop(X86Registers::esi); + pop(X86Registers::edi); #endif ret(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h index 8562cac..294c3d0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h @@ -63,26 +63,26 @@ namespace JSC { } #if PLATFORM(X86) - static const RegisterID input = X86::eax; - static const RegisterID index = X86::edx; - static const RegisterID length = X86::ecx; - static const RegisterID output = X86::edi; + static const RegisterID input = X86Registers::eax; + static const RegisterID index = X86Registers::edx; + static const RegisterID length = X86Registers::ecx; + static const RegisterID output = X86Registers::edi; - static const RegisterID character = X86::esi; - static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match. + static const RegisterID character = X86Registers::esi; + static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match. - static const RegisterID returnRegister = X86::eax; + static const RegisterID returnRegister = X86Registers::eax; #endif #if PLATFORM(X86_64) - static const RegisterID input = X86::edi; - static const RegisterID index = X86::esi; - static const RegisterID length = X86::edx; - static const RegisterID output = X86::ecx; + static const RegisterID input = X86Registers::edi; + static const RegisterID index = X86Registers::esi; + static const RegisterID length = X86Registers::edx; + static const RegisterID output = X86Registers::ecx; - static const RegisterID character = X86::eax; - static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match. + static const RegisterID character = X86Registers::eax; + static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match. - static const RegisterID returnRegister = X86::eax; + static const RegisterID returnRegister = X86Registers::eax; #endif void generateEnter(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wscript b/src/3rdparty/javascriptcore/JavaScriptCore/wscript new file mode 100644 index 0000000..9dd37c9 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wscript @@ -0,0 +1,103 @@ +#! /usr/bin/env python + +# Copyright (C) 2009 Kevin Ollivier 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. +# +# JavaScriptCore build script for the waf build system + +import commands + +from settings import * + +jscore_excludes = ['jsc.cpp', 'ucptable.cpp', 'GOwnPtr.cpp'] +jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp'])) + +sources = [] + +jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp', '*None.cpp'])) + +if building_on_win32: + jscore_excludes += ['ExecutableAllocatorPosix.cpp', 'MarkStackPosix.cpp'] + sources += ['jit/ExecutableAllocatorWin.cpp', 'runtime/MarkStackWin.cpp'] +else: + jscore_excludes.append('JSStringRefBSTR.cpp') + +def generate_jscore_derived_sources(): + # build the derived sources + js_dir = jscore_dir + if building_on_win32: + js_dir = get_output('cygpath --unix "%s"' % js_dir) + derived_sources_dir = os.path.join(jscore_dir, 'DerivedSources') + if not os.path.exists(derived_sources_dir): + os.mkdir(derived_sources_dir) + + olddir = os.getcwd() + os.chdir(derived_sources_dir) + + command = 'make -f %s/DerivedSources.make JavaScriptCore=%s BUILT_PRODUCTS_DIR=%s all FEATURE_DEFINES="%s"' % (js_dir, js_dir, js_dir, ' '.join(feature_defines)) + os.system(command) + os.chdir(olddir) + +def set_options(opt): + common_set_options(opt) + +def configure(conf): + common_configure(conf) + generate_jscore_derived_sources() + +def build(bld): + import Options + + full_dirs = get_dirs_for_features(jscore_dir, features=[build_port], dirs=jscore_dirs) + + includes = common_includes + full_dirs + + # 1. A simple program + jscore = bld.new_task_gen( + features = 'cxx cstaticlib', + includes = '. .. assembler wrec DerivedSources ForwardingHeaders ' + ' '.join(includes), + source = sources, + target = 'jscore', + uselib = 'WX ICU ' + get_config(), + uselib_local = '', + install_path = output_dir) + + jscore.find_sources_in_dirs(full_dirs, excludes = jscore_excludes) + + obj = bld.new_task_gen( + features = 'cxx cprogram', + includes = '. .. assembler wrec DerivedSources ForwardingHeaders ' + ' '.join(includes), + source = 'jsc.cpp', + target = 'jsc', + uselib = 'WX ICU ' + get_config(), + uselib_local = 'jscore', + install_path = output_dir, + ) + + # we'll get an error if exceptions are on because of an unwind error when using __try + if building_on_win32: + flags = obj.env.CXXFLAGS + flags.remove('/EHsc') + obj.env.CXXFLAGS = flags + + bld.install_files(os.path.join(output_dir, 'JavaScriptCore'), 'API/*.h') diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h index d691357..b68e70c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h @@ -144,8 +144,10 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #if ASSERT_DISABLED #define ASSERT(assertion) ((void)0) -#if COMPILER(MSVC7) || COMPILER(WINSCW) +#if COMPILER(MSVC7) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif PLATFORM(SYMBIAN) +#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) #endif /* COMPILER(MSVC7) */ @@ -160,8 +162,10 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann CRASH(); \ } \ while (0) -#if COMPILER(MSVC7) || COMPILER(WINSCW) +#if COMPILER(MSVC7) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif PLATFORM(SYMBIAN) +#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) do \ if (!(assertion)) { \ @@ -203,10 +207,12 @@ while (0) /* FATAL */ -#if FATAL_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) +#if FATAL_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define FATAL(...) ((void)0) #elif COMPILER(MSVC7) #define FATAL() ((void)0) +#elif PLATFORM(SYMBIAN) +#define FATAL(args...) ((void)0) #else #define FATAL(...) do { \ WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \ @@ -216,20 +222,24 @@ while (0) /* LOG_ERROR */ -#if ERROR_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) +#if ERROR_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG_ERROR(...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#elif COMPILER(MSVC7) #define LOG_ERROR() ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG_ERROR(args...) ((void)0) #else #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) #endif /* LOG */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) +#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG(channel, ...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#elif COMPILER(MSVC7) #define LOG() ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG(channel, args...) ((void)0) #else #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) @@ -238,10 +248,12 @@ while (0) /* LOG_VERBOSE */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) +#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG_VERBOSE(channel, ...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#elif COMPILER(MSVC7) #define LOG_VERBOSE(channel) ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG_VERBOSE(channel, args...) ((void)0) #else #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ByteArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ByteArray.h index 96e9cc2..f5f5ded 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ByteArray.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ByteArray.h @@ -45,6 +45,13 @@ namespace WTF { m_data[index] = static_cast<unsigned char>(value + 0.5); } + void set(unsigned index, unsigned char value) + { + if (index >= m_size) + return; + m_data[index] = value; + } + bool get(unsigned index, unsigned char& result) const { if (index >= m_size) @@ -53,6 +60,12 @@ namespace WTF { return true; } + unsigned char get(unsigned index) const + { + ASSERT(index < m_size); + return m_data[index]; + } + unsigned char* data() { return m_data; } void deref() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp index 73c2c5c..a3d5290 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * Copyright (C) 2008 Google Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,6 +34,7 @@ #include "CurrentTime.h" #if PLATFORM(WIN_OS) + // Windows is first since we want to use hires timers, despite PLATFORM(CF) // being defined. // If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod. @@ -40,13 +42,17 @@ #include <windows.h> #include <math.h> #include <stdint.h> -#if HAVE(SYS_TIMEB_H) +#include <time.h> + +#if USE(QUERY_PERFORMANCE_COUNTER) +#if PLATFORM(WINCE) +extern "C" time_t mktime(struct tm *t); +#else #include <sys/timeb.h> -#endif -#if !PLATFORM(WINCE) #include <sys/types.h> #endif -#include <time.h> +#endif + #elif PLATFORM(CF) #include <CoreFoundation/CFDate.h> #elif PLATFORM(GTK) @@ -63,6 +69,8 @@ const double msPerSecond = 1000.0; #if PLATFORM(WIN_OS) +#if USE(QUERY_PERFORMANCE_COUNTER) + static LARGE_INTEGER qpcFrequency; static bool syncedTime; @@ -188,6 +196,55 @@ double currentTime() return utc / 1000.0; } +#else + +static double currentSystemTime() +{ + FILETIME ft; + GetCurrentFT(&ft); + + // As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a + // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can + // prevent alignment faults on 64-bit Windows). + + ULARGE_INTEGER t; + memcpy(&t, &ft, sizeof(t)); + + // Windows file times are in 100s of nanoseconds. + // To convert to seconds, we have to divide by 10,000,000, which is more quickly + // done by multiplying by 0.0000001. + + // Between January 1, 1601 and January 1, 1970, there were 369 complete years, + // of which 89 were leap years (1700, 1800, and 1900 were not leap years). + // That is a total of 134774 days, which is 11644473600 seconds. + + return t.QuadPart * 0.0000001 - 11644473600.0; +} + +double currentTime() +{ + static bool init = false; + static double lastTime; + static DWORD lastTickCount; + if (!init) { + lastTime = currentSystemTime(); + lastTickCount = GetTickCount(); + init = true; + return lastTime; + } + + DWORD tickCountNow = GetTickCount(); + DWORD elapsed = tickCountNow - lastTickCount; + double timeNow = lastTime + (double)elapsed / 1000.; + if (elapsed >= 0x7FFFFFFF) { + lastTime = timeNow; + lastTickCount = tickCountNow; + } + return timeNow; +} + +#endif // USE(QUERY_PERFORMANCE_COUNTER) + #elif PLATFORM(CF) double currentTime() diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp index 0b76649..0386494 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp @@ -65,6 +65,11 @@ #include <notify.h> #endif +#if PLATFORM(WINCE) +extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); +extern "C" struct tm * localtime(const time_t *timer); +#endif + #if HAVE(SYS_TIME_H) #include <sys/time.h> #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DisallowCType.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DisallowCType.h index 5dccb0e..436f7f2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DisallowCType.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DisallowCType.h @@ -54,21 +54,21 @@ #undef tolower #undef toupper -#define isalnum WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isalpha WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isascii WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isblank WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define iscntrl WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isdigit WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isgraph WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define islower WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isprint WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define ispunct WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isspace WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isupper WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isxdigit WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define toascii WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define tolower WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define toupper WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isalnum isalnum_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isalpha isalpha_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isascii isascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isblank isblank_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define iscntrl iscntrl_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isdigit isdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isgraph isgraph_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define islower islower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isprint isprint_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define ispunct ispunct_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isspace isspace_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isupper isupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define isxdigit isxdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define toascii toascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define tolower tolower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h +#define toupper toupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastAllocBase.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastAllocBase.h index 9fcbbc1..81b1de0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastAllocBase.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastAllocBase.h @@ -301,6 +301,16 @@ namespace WTF { fastFree(p); } + template <typename T> + inline void fastDeleteSkippingDestructor(T* p) + { + if (!p) + return; + + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); + fastFree(p); + } + namespace Internal { // This is a support template for fastDeleteArray. // This handles the case wherein T has a trivial dtor. @@ -397,7 +407,7 @@ namespace WTF { } // namespace WTF -// Using WTF::FastAllocBase to avoid using FastAllocBase's explicit qualification by WTF::. using WTF::FastAllocBase; +using WTF::fastDeleteSkippingDestructor; #endif // FastAllocBase_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp index c855a41..afb0220 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2005, 2007, Google Inc. // All rights reserved. -// Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. +// Copyright (C) 2005, 2006, 2007, 2008, 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 @@ -89,12 +89,20 @@ #endif #endif -#if !defined(USE_SYSTEM_MALLOC) && defined(NDEBUG) +#if !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) && defined(NDEBUG) #define FORCE_SYSTEM_MALLOC 0 #else #define FORCE_SYSTEM_MALLOC 1 #endif +// Use a background thread to periodically scavenge memory to release back to the system +// https://bugs.webkit.org/show_bug.cgi?id=27900: don't turn this on for Tiger until we have figured out why it caused a crash. +#if defined(BUILDING_ON_TIGER) +#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0 +#else +#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 +#endif + #ifndef NDEBUG namespace WTF { @@ -170,10 +178,10 @@ void* fastZeroedMalloc(size_t n) return result; } -void* tryFastZeroedMalloc(size_t n) +TryMallocReturnValue tryFastZeroedMalloc(size_t n) { - void* result = tryFastMalloc(n); - if (!result) + void* result; + if (!tryFastMalloc(n).getValue(result)) return 0; memset(result, 0, n); return result; @@ -192,7 +200,7 @@ void* tryFastZeroedMalloc(size_t n) namespace WTF { -void* tryFastMalloc(size_t n) +TryMallocReturnValue tryFastMalloc(size_t n) { ASSERT(!isForbidden()); @@ -218,7 +226,9 @@ void* fastMalloc(size_t n) ASSERT(!isForbidden()); #if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - void* result = tryFastMalloc(n); + TryMallocReturnValue returnValue = tryFastMalloc(n); + void* result; + returnValue.getValue(result); #else void* result = malloc(n); #endif @@ -228,7 +238,7 @@ void* fastMalloc(size_t n) return result; } -void* tryFastCalloc(size_t n_elements, size_t element_size) +TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size) { ASSERT(!isForbidden()); @@ -256,7 +266,9 @@ void* fastCalloc(size_t n_elements, size_t element_size) ASSERT(!isForbidden()); #if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - void* result = tryFastCalloc(n_elements, element_size); + TryMallocReturnValue returnValue = tryFastCalloc(n_elements, element_size); + void* result; + returnValue.getValue(result); #else void* result = calloc(n_elements, element_size); #endif @@ -283,7 +295,7 @@ void fastFree(void* p) #endif } -void* tryFastRealloc(void* p, size_t n) +TryMallocReturnValue tryFastRealloc(void* p, size_t n) { ASSERT(!isForbidden()); @@ -315,7 +327,9 @@ void* fastRealloc(void* p, size_t n) ASSERT(!isForbidden()); #if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - void* result = tryFastRealloc(p, n); + TryMallocReturnValue returnValue = tryFastRealloc(p, n); + void* result; + returnValue.getValue(result); #else void* result = realloc(p, n); #endif @@ -531,7 +545,7 @@ static const size_t kNumClasses = 68; static const size_t kPageMapBigAllocationThreshold = 128 << 20; // Minimum number of pages to fetch from system at a time. Must be -// significantly bigger than kBlockSize to amortize system-call +// significantly bigger than kPageSize to amortize system-call // overhead, and also to reduce external fragementation. Also, we // should keep this value big because various incarnations of Linux // have small limits on the number of mmap() regions per @@ -1187,6 +1201,32 @@ template <> class MapSelector<32> { // contiguous runs of pages (called a "span"). // ------------------------------------------------------------------------- +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +// The central page heap collects spans of memory that have been deleted but are still committed until they are released +// back to the system. We use a background thread to periodically scan the list of free spans and release some back to the +// system. Every 5 seconds, the background thread wakes up and does the following: +// - Check if we needed to commit memory in the last 5 seconds. If so, skip this scavenge because it's a sign that we are short +// of free committed pages and so we should not release them back to the system yet. +// - Otherwise, go through the list of free spans (from largest to smallest) and release up to a fraction of the free committed pages +// back to the system. +// - If the number of free committed pages reaches kMinimumFreeCommittedPageCount, we can stop the scavenging and block the +// scavenging thread until the number of free committed pages goes above kMinimumFreeCommittedPageCount. + +// Background thread wakes up every 5 seconds to scavenge as long as there is memory available to return to the system. +static const int kScavengeTimerDelayInSeconds = 5; + +// Number of free committed pages that we want to keep around. +static const size_t kMinimumFreeCommittedPageCount = 512; + +// During a scavenge, we'll release up to a fraction of the free committed pages. +#if PLATFORM(WIN) +// We are slightly less aggressive in releasing memory on Windows due to performance reasons. +static const int kMaxScavengeAmountFactor = 3; +#else +static const int kMaxScavengeAmountFactor = 2; +#endif +#endif + class TCMalloc_PageHeap { public: void init(); @@ -1286,6 +1326,14 @@ class TCMalloc_PageHeap { // Bytes allocated from system uint64_t system_bytes_; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + // Number of pages kept in free lists that are still committed. + Length free_committed_pages_; + + // Number of pages that we committed in the last scavenge wait interval. + Length pages_committed_since_last_scavenge_; +#endif + bool GrowHeap(Length n); // REQUIRES span->length >= n @@ -1308,9 +1356,11 @@ class TCMalloc_PageHeap { // span of exactly the specified length. Else, returns NULL. Span* AllocLarge(Length n); +#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY // Incrementally release some memory to the system. // IncrementalScavenge(n) is called whenever n pages are freed. void IncrementalScavenge(Length n); +#endif // Number of pages to deallocate before doing more scavenging int64_t scavenge_counter_; @@ -1321,6 +1371,24 @@ class TCMalloc_PageHeap { #if defined(WTF_CHANGES) && PLATFORM(DARWIN) friend class FastMallocZone; #endif + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + static NO_RETURN void* runScavengerThread(void*); + + NO_RETURN void scavengerThread(); + + void scavenge(); + + inline bool shouldContinueScavenging() const; + + pthread_mutex_t m_scavengeMutex; + + pthread_cond_t m_scavengeCondition; + + // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or + // it's blocked waiting for more pages to be deleted. + bool m_scavengeThreadActive; +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY }; void TCMalloc_PageHeap::init() @@ -1329,6 +1397,12 @@ void TCMalloc_PageHeap::init() pagemap_cache_ = PageMapCache(0); free_pages_ = 0; system_bytes_ = 0; + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + free_committed_pages_ = 0; + pages_committed_since_last_scavenge_ = 0; +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + scavenge_counter_ = 0; // Start scavenging at kMaxPages list scavenge_index_ = kMaxPages-1; @@ -1339,8 +1413,68 @@ void TCMalloc_PageHeap::init() DLL_Init(&free_[i].normal); DLL_Init(&free_[i].returned); } + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pthread_mutex_init(&m_scavengeMutex, 0); + pthread_cond_init(&m_scavengeCondition, 0); + m_scavengeThreadActive = true; + pthread_t thread; + pthread_create(&thread, 0, runScavengerThread, this); +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +} + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +void* TCMalloc_PageHeap::runScavengerThread(void* context) +{ + static_cast<TCMalloc_PageHeap*>(context)->scavengerThread(); +#if COMPILER(MSVC) + // Without this, Visual Studio will complain that this method does not return a value. + return 0; +#endif } +void TCMalloc_PageHeap::scavenge() +{ + // If we have to commit memory in the last 5 seconds, it means we don't have enough free committed pages + // for the amount of allocations that we do. So hold off on releasing memory back to the system. + if (pages_committed_since_last_scavenge_ > 0) { + pages_committed_since_last_scavenge_ = 0; + return; + } + Length pagesDecommitted = 0; + for (int i = kMaxPages; i >= 0; i--) { + SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i]; + if (!DLL_IsEmpty(&slist->normal)) { + // Release the last span on the normal portion of this list + Span* s = slist->normal.prev; + // Only decommit up to a fraction of the free committed pages if pages_allocated_since_last_scavenge_ > 0. + if ((pagesDecommitted + s->length) * kMaxScavengeAmountFactor > free_committed_pages_) + continue; + DLL_Remove(s); + TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), + static_cast<size_t>(s->length << kPageShift)); + if (!s->decommitted) { + pagesDecommitted += s->length; + s->decommitted = true; + } + DLL_Prepend(&slist->returned, s); + // We can stop scavenging if the number of free committed pages left is less than or equal to the minimum number we want to keep around. + if (free_committed_pages_ <= kMinimumFreeCommittedPageCount + pagesDecommitted) + break; + } + } + pages_committed_since_last_scavenge_ = 0; + ASSERT(free_committed_pages_ >= pagesDecommitted); + free_committed_pages_ -= pagesDecommitted; +} + +inline bool TCMalloc_PageHeap::shouldContinueScavenging() const +{ + return free_committed_pages_ > kMinimumFreeCommittedPageCount; +} + +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + inline Span* TCMalloc_PageHeap::New(Length n) { ASSERT(Check()); ASSERT(n > 0); @@ -1366,7 +1500,18 @@ inline Span* TCMalloc_PageHeap::New(Length n) { if (result->decommitted) { TCMalloc_SystemCommit(reinterpret_cast<void*>(result->start << kPageShift), static_cast<size_t>(n << kPageShift)); result->decommitted = false; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += n; +#endif + } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + else { + // The newly allocated memory is from a span that's in the normal span list (already committed). Update the + // free committed pages count. + ASSERT(free_committed_pages_ >= n); + free_committed_pages_ -= n; } +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY ASSERT(Check()); free_pages_ -= n; return result; @@ -1426,7 +1571,18 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) { if (best->decommitted) { TCMalloc_SystemCommit(reinterpret_cast<void*>(best->start << kPageShift), static_cast<size_t>(n << kPageShift)); best->decommitted = false; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += n; +#endif + } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + else { + // The newly allocated memory is from a span that's in the normal span list (already committed). Update the + // free committed pages count. + ASSERT(free_committed_pages_ >= n); + free_committed_pages_ -= n; } +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY ASSERT(Check()); free_pages_ -= n; return best; @@ -1508,6 +1664,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // necessary. We do not bother resetting the stale pagemap // entries for the pieces we are merging together because we only // care about the pagemap entries for the boundaries. +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + // Track the total size of the neighboring free spans that are committed. + Length neighboringCommittedSpansLength = 0; +#endif const PageID p = span->start; const Length n = span->length; Span* prev = GetDescriptor(p-1); @@ -1515,6 +1675,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // Merge preceding span into this span ASSERT(prev->start + prev->length == p); const Length len = prev->length; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (!prev->decommitted) + neighboringCommittedSpansLength += len; +#endif mergeDecommittedStates(span, prev); DLL_Remove(prev); DeleteSpan(prev); @@ -1528,6 +1692,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // Merge next span into this span ASSERT(next->start == p+n); const Length len = next->length; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (!next->decommitted) + neighboringCommittedSpansLength += len; +#endif mergeDecommittedStates(span, next); DLL_Remove(next); DeleteSpan(next); @@ -1551,10 +1719,27 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { } free_pages_ += n; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (span->decommitted) { + // If the merged span is decommitted, that means we decommitted any neighboring spans that were + // committed. Update the free committed pages count. + free_committed_pages_ -= neighboringCommittedSpansLength; + } else { + // If the merged span remains committed, add the deleted span's size to the free committed pages count. + free_committed_pages_ += n; + } + + // Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system. + if (!m_scavengeThreadActive && shouldContinueScavenging()) + pthread_cond_signal(&m_scavengeCondition); +#else IncrementalScavenge(n); +#endif + ASSERT(Check()); } +#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY void TCMalloc_PageHeap::IncrementalScavenge(Length n) { // Fast path; not yet time to release memory scavenge_counter_ -= n; @@ -1592,6 +1777,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) { // Nothing to scavenge, delay for a while scavenge_counter_ = kDefaultReleaseDelay; } +#endif void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) { // Associate span object with all interior pages as well @@ -1703,6 +1889,10 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) { } ask = actual_size >> kPageShift; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += ask; +#endif + uint64_t old_system_bytes = system_bytes_; system_bytes_ += (ask << kPageShift); const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; @@ -2083,6 +2273,34 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +#if PLATFORM(WIN) +static void sleep(unsigned seconds) +{ + ::Sleep(seconds * 1000); +} +#endif + +void TCMalloc_PageHeap::scavengerThread() +{ + while (1) { + if (!shouldContinueScavenging()) { + pthread_mutex_lock(&m_scavengeMutex); + m_scavengeThreadActive = false; + // Block until there are enough freed pages to release back to the system. + pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex); + m_scavengeThreadActive = true; + pthread_mutex_unlock(&m_scavengeMutex); + } + sleep(kScavengeTimerDelayInSeconds); + { + SpinLockHolder h(&pageheap_lock); + pageheap->scavenge(); + } + } +} +#endif + // If TLS is available, we also store a copy // of the per-thread object in a __thread variable // since __thread variables are faster to read @@ -3364,7 +3582,7 @@ void* fastMalloc(size_t size) return malloc<true>(size); } -void* tryFastMalloc(size_t size) +TryMallocReturnValue tryFastMalloc(size_t size) { return malloc<false>(size); } @@ -3425,7 +3643,7 @@ void* fastCalloc(size_t n, size_t elem_size) return calloc<true>(n, elem_size); } -void* tryFastCalloc(size_t n, size_t elem_size) +TryMallocReturnValue tryFastCalloc(size_t n, size_t elem_size) { return calloc<false>(n, elem_size); } @@ -3489,7 +3707,7 @@ void* fastRealloc(void* old_ptr, size_t new_size) return realloc<true>(old_ptr, new_size); } -void* tryFastRealloc(void* old_ptr, size_t new_size) +TryMallocReturnValue tryFastRealloc(void* old_ptr, size_t new_size) { return realloc<false>(old_ptr, new_size); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h index 61ebe32..b23e7b0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,24 +22,56 @@ #define WTF_FastMalloc_h #include "Platform.h" +#include "PossiblyNull.h" #include <stdlib.h> #include <new> namespace WTF { // These functions call CRASH() if an allocation fails. - void* fastMalloc(size_t n); - void* fastZeroedMalloc(size_t n); - void* fastCalloc(size_t n_elements, size_t element_size); - void* fastRealloc(void* p, size_t n); + void* fastMalloc(size_t); + void* fastZeroedMalloc(size_t); + void* fastCalloc(size_t numElements, size_t elementSize); + void* fastRealloc(void*, size_t); + + struct TryMallocReturnValue { + TryMallocReturnValue(void* data) + : m_data(data) + { + } + TryMallocReturnValue(const TryMallocReturnValue& source) + : m_data(source.m_data) + { + source.m_data = 0; + } + ~TryMallocReturnValue() { ASSERT(!m_data); } + template <typename T> bool getValue(T& data) WARN_UNUSED_RETURN; + template <typename T> operator PossiblyNull<T>() + { + T value; + getValue(value); + return PossiblyNull<T>(value); + } + private: + mutable void* m_data; + }; + + template <typename T> bool TryMallocReturnValue::getValue(T& data) + { + union u { void* data; T target; } res; + res.data = m_data; + data = res.target; + bool returnValue = !!m_data; + m_data = 0; + return returnValue; + } - // These functions return NULL if an allocation fails. - void* tryFastMalloc(size_t n); - void* tryFastZeroedMalloc(size_t n); - void* tryFastCalloc(size_t n_elements, size_t element_size); - void* tryFastRealloc(void* p, size_t n); + TryMallocReturnValue tryFastMalloc(size_t n); + TryMallocReturnValue tryFastZeroedMalloc(size_t n); + TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size); + TryMallocReturnValue tryFastRealloc(void* p, size_t n); - void fastFree(void* p); + void fastFree(void*); #ifndef NDEBUG void fastMallocForbid(); @@ -172,22 +204,24 @@ using WTF::fastMallocAllow; #define WTF_PRIVATE_INLINE inline #endif -#ifndef _CRTDBG_MAP_ALLOC +#if !defined(_CRTDBG_MAP_ALLOC) && !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) -#if !defined(USE_SYSTEM_MALLOC) || !(USE_SYSTEM_MALLOC) -WTF_PRIVATE_INLINE void* operator new(size_t s) { return fastMalloc(s); } -WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); } -WTF_PRIVATE_INLINE void* operator new[](size_t s) { return fastMalloc(s); } -WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); } +// The nothrow functions here are actually not all that helpful, because fastMalloc will +// call CRASH() rather than returning 0, and returning 0 is what nothrow is all about. +// But since WebKit code never uses exceptions or nothrow at all, this is probably OK. +// Long term we will adopt FastAllocBase.h everywhere, and and replace this with +// debug-only code to make sure we don't use the system malloc via the default operator +// new by accident. -#if PLATFORM(WINCE) -WTF_PRIVATE_INLINE void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } +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); } WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); } -WTF_PRIVATE_INLINE void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } +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); } WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); } -#endif -#endif -#endif // _CRTDBG_MAP_ALLOC +#endif #endif /* WTF_FastMalloc_h */ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h index ec809e5..3906a36 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h @@ -29,6 +29,8 @@ namespace WTF { template<typename Value, typename HashFunctions, typename Traits> class HashSet; template<typename Value, typename HashFunctions, typename Traits> void deleteAllValues(const HashSet<Value, HashFunctions, Traits>&); + template<typename Value, typename HashFunctions, typename Traits> + void fastDeleteAllValues(const HashSet<Value, HashFunctions, Traits>&); template<typename T> struct IdentityExtractor; @@ -91,6 +93,7 @@ namespace WTF { private: friend void deleteAllValues<>(const HashSet&); + friend void fastDeleteAllValues<>(const HashSet&); HashTableType m_impl; }; @@ -257,6 +260,21 @@ namespace WTF { { deleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl); } + + template<typename ValueType, typename HashTableType> + void fastDeleteAllValues(HashTableType& collection) + { + typedef typename HashTableType::const_iterator iterator; + iterator end = collection.end(); + for (iterator it = collection.begin(); it != end; ++it) + fastDelete(*it); + } + + template<typename T, typename U, typename V> + inline void fastDeleteAllValues(const HashSet<T, U, V>& collection) + { + fastDeleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl); + } template<typename T, typename U, typename V, typename W> inline void copyToVector(const HashSet<T, U, V>& collection, W& vector) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h index 9f9a354..d863226 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h @@ -34,13 +34,8 @@ namespace WTF { ListRefPtr(const RefPtr<T>& o) : RefPtr<T>(o) {} // see comment in PassRefPtr.h for why this takes const reference template <typename U> ListRefPtr(const PassRefPtr<U>& o) : RefPtr<T>(o) {} - - ~ListRefPtr() - { - RefPtr<T> reaper = this->release(); - while (reaper && reaper->hasOneRef()) - reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper - } + + ~ListRefPtr(); ListRefPtr& operator=(T* optr) { RefPtr<T>::operator=(optr); return *this; } ListRefPtr& operator=(const RefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; } @@ -49,6 +44,17 @@ namespace WTF { template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } }; + template <typename T> +#if !COMPILER(WINSCW) + inline +#endif + ListRefPtr<T>::~ListRefPtr() + { + RefPtr<T> reaper = this->release(); + while (reaper && reaper->hasOneRef()) + reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper + } + template <typename T> inline T* getPtr(const ListRefPtr<T>& p) { return p.get(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp index 3c19b7a..e999094 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp @@ -29,9 +29,9 @@ #include "config.h" #include "MainThread.h" +#include "StdLibExtras.h" #include "CurrentTime.h" #include "Deque.h" -#include "StdLibExtras.h" #include "Threading.h" namespace WTF { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Noncopyable.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Noncopyable.h index c50c9d8..60a46e2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Noncopyable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Noncopyable.h @@ -28,7 +28,7 @@ namespace WTFNoncopyable { - class Noncopyable { + class Noncopyable : public FastAllocBase { Noncopyable(const Noncopyable&); Noncopyable& operator=(const Noncopyable&); protected: diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h index d80ed62..ae398d3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h @@ -28,11 +28,34 @@ namespace WTF { template<typename T> class RefPtr; template<typename T> class PassRefPtr; template <typename T> PassRefPtr<T> adoptRef(T*); + + // Remove inline for winscw compiler to prevent the compiler agressively resolving + // T::deref(), which will fail compiling when PassRefPtr<T> is used as class member + // or function arguments before T is defined. + template<typename T> +#if !COMPILER(WINSCW) + inline +#endif + void derefIfNotNull(T* ptr) + { + if (UNLIKELY(ptr != 0)) + ptr->deref(); + } + + template<typename T> +#if !COMPILER(WINSCW) + inline +#endif + void refIfNotNull(T* ptr) + { + if (UNLIKELY(ptr != 0)) + ptr->ref(); + } template<typename T> class PassRefPtr { public: PassRefPtr() : m_ptr(0) {} - PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); } + PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } // It somewhat breaks the type system to allow transfer of ownership out of // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr // temporaries, and we don't really have a need to use real const PassRefPtrs @@ -40,14 +63,14 @@ namespace WTF { PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {} template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } - ALWAYS_INLINE ~PassRefPtr() { if (UNLIKELY(m_ptr != 0)) m_ptr->deref(); } - + ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } + template <class U> - PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); } + PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); } T* get() const { return m_ptr; } - void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; } + void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; } T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; } T& operator*() const { return *m_ptr; } @@ -56,12 +79,10 @@ namespace WTF { bool operator!() const { return !m_ptr; } // This conversion operator allows implicit conversion to bool but not to other integer types. -#if COMPILER(WINSCW) - operator bool() const { return m_ptr; } -#else - typedef T* PassRefPtr::*UnspecifiedBoolType; + // Parenthesis is needed for winscw compiler to resolve class qualifier in this case. + typedef T* (PassRefPtr::*UnspecifiedBoolType); operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; } -#endif + PassRefPtr& operator=(T*); PassRefPtr& operator=(const PassRefPtr&); template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&); @@ -77,23 +98,19 @@ namespace WTF { template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); - if (optr) - optr->ref(); + refIfNotNull(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) { - if (optr) - optr->ref(); + refIfNotNull(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } @@ -101,8 +118,7 @@ namespace WTF { { T* ptr = m_ptr; m_ptr = ref.releaseRef(); - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } @@ -110,8 +126,7 @@ namespace WTF { { T* ptr = m_ptr; m_ptr = ref.releaseRef(); - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h index fa37d55..cc40336 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h @@ -63,7 +63,6 @@ /* Note that for this platform PLATFORM(WIN_OS) is also defined. */ #if defined(_WIN32_WCE) #define WTF_PLATFORM_WINCE 1 -#include <ce_time.h> #endif /* PLATFORM(LINUX) */ @@ -146,6 +145,7 @@ || defined(__unix) \ || defined(__unix__) \ || PLATFORM(AIX) \ + || defined(__HAIKU__) \ || defined(__QNXNTO__) #define WTF_PLATFORM_UNIX 1 #endif @@ -171,6 +171,8 @@ #define WTF_PLATFORM_WX 1 #elif defined(BUILDING_GTK__) #define WTF_PLATFORM_GTK 1 +#elif defined(BUILDING_HAIKU__) +#define WTF_PLATFORM_HAIKU 1 #elif PLATFORM(DARWIN) #define WTF_PLATFORM_MAC 1 #elif PLATFORM(WIN_OS) @@ -217,7 +219,7 @@ /* Makes PLATFORM(WIN) default to PLATFORM(CAIRO) */ /* FIXME: This should be changed from a blacklist to a whitelist */ -#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !PLATFORM(WINCE) +#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !PLATFORM(WINCE) && !PLATFORM(HAIKU) #define WTF_PLATFORM_CAIRO 1 #endif @@ -243,17 +245,17 @@ #endif /* PLATFORM(ARM) */ +#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) + #if defined(arm) \ - || defined(__arm__) + || defined(__arm__) \ + || defined(__MARM__) #define WTF_PLATFORM_ARM 1 #if defined(__ARMEB__) #define WTF_PLATFORM_BIG_ENDIAN 1 -#elif !defined(__ARM_EABI__) && !defined(__ARMEB__) && !defined(__VFP_FP__) +#elif !defined(__ARM_EABI__) && !defined(__EABI__) && !defined(__VFP_FP__) #define WTF_PLATFORM_MIDDLE_ENDIAN 1 #endif -#if !defined(__ARM_EABI__) -#define WTF_PLATFORM_FORCE_PACK 1 -#endif #define ARM_ARCH_VERSION 3 #if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) #undef ARM_ARCH_VERSION @@ -261,22 +263,35 @@ #endif #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) + || defined(__ARM_ARCH_5TEJ__) || defined(__MARM_ARMV5__) #undef ARM_ARCH_VERSION #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(__ARM_ARCH_6ZK__) || defined(__ARMV6__) #undef ARM_ARCH_VERSION #define ARM_ARCH_VERSION 6 #endif -#if defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7A__) || defined(__ARMV7__) #undef ARM_ARCH_VERSION #define ARM_ARCH_VERSION 7 #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__) +# define WTF_PLATFORM_ARM_TRADITIONAL 0 +# define WTF_PLATFORM_ARM_THUMB2 1 +# elif PLATFORM_ARM_ARCH(4) || PLATFORM_ARM_ARCH(5) +# define WTF_PLATFORM_ARM_TRADITIONAL 1 +# define WTF_PLATFORM_ARM_THUMB2 0 +# else +# error "Not supported ARM architecture" +# endif +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(ARM_THUMB2) /* Sanity Check */ +# error "Cannot use both of WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 platforms" +#endif // !defined(ARM_TRADITIONAL) && !defined(ARM_THUMB2) #endif /* ARM */ -#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) /* PLATFORM(X86) */ #if defined(__i386__) \ @@ -299,7 +314,7 @@ #endif /* PLATFORM(SPARC64) */ -#if defined(__sparc64__) +#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9) #define WTF_PLATFORM_SPARC64 1 #define WTF_PLATFORM_BIG_ENDIAN 1 #endif @@ -316,6 +331,11 @@ #if defined(__ia64) || defined(__ia64__) || defined(_M_IA64) #define WTF_PLATFORM_IA64 1 +/* 32-bit mode on Itanium */ +#if !defined(__LP64__) +#define WTF_PLATFORM_IA64_32 1 +#endif + /* Itanium can be both big- and little-endian we need to determine at compile time which one it is. - HP's aCC compiler only compiles big-endian (so HP-UXi is always big-endian) @@ -408,6 +428,11 @@ #define ENABLE_JSC_MULTIPLE_THREADS 1 #endif +/* On Windows, use QueryPerformanceCounter by default */ +#if PLATFORM(WIN_OS) +#define WTF_USE_QUERY_PERFORMANCE_COUNTER 1 +#endif + #if PLATFORM(WINCE) && !PLATFORM(QT) #undef ENABLE_JSC_MULTIPLE_THREADS #define ENABLE_JSC_MULTIPLE_THREADS 0 @@ -438,6 +463,8 @@ /* for Unicode, KDE uses Qt */ #if PLATFORM(KDE) || PLATFORM(QT) #define WTF_USE_QT4_UNICODE 1 +#elif PLATFORM(WINCE) +#define WTF_USE_WINCE_UNICODE 1 #elif PLATFORM(GTK) /* The GTK+ Unicode backend is configurable */ #else @@ -465,7 +492,10 @@ #if PLATFORM(IPHONE) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define ENABLE_CONTEXT_MENUS 0 +#define ENABLE_DRAG_SUPPORT 0 #define ENABLE_FTPDIR 1 +#define ENABLE_INSPECTOR 0 #define ENABLE_MAC_JAVA_BRIDGE 0 #define ENABLE_ICONDATABASE 0 #define ENABLE_GEOLOCATION 1 @@ -480,8 +510,6 @@ #if PLATFORM(WX) #define ENABLE_ASSEMBLER 1 -#define WTF_USE_CURL 1 -#define WTF_USE_PTHREADS 1 #endif #if PLATFORM(GTK) @@ -490,6 +518,14 @@ #endif #endif +#if PLATFORM(HAIKU) +#define HAVE_POSIX_MEMALIGN 1 +#define WTF_USE_CURL 1 +#define WTF_USE_PTHREADS 1 +#define USE_SYSTEM_MALLOC 1 +#define ENABLE_NETSCAPE_PLUGIN_API 0 +#endif + #if !defined(HAVE_ACCESSIBILITY) #if PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM) #define HAVE_ACCESSIBILITY 1 @@ -501,7 +537,8 @@ #endif #if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(QNX) \ - && !PLATFORM(SYMBIAN) && !COMPILER(RVCT) && !PLATFORM(AIX) && !PLATFORM(HPUX) + && !PLATFORM(SYMBIAN) && !PLATFORM(HAIKU) && !COMPILER(RVCT) && !PLATFORM(AIX) \ + && !PLATFORM(HPUX) #define HAVE_TM_GMTOFF 1 #define HAVE_TM_ZONE 1 #define HAVE_TIMEGM 1 @@ -565,7 +602,10 @@ /* FIXME: is this actually used or do other platforms generate their own config.h? */ #define HAVE_ERRNO_H 1 +/* As long as Haiku doesn't have a complete support of locale this will be disabled. */ +#if !PLATFORM(HAIKU) #define HAVE_LANGINFO_H 1 +#endif #define HAVE_MMAP 1 #define HAVE_SBRK 1 #define HAVE_STRINGS_H 1 @@ -598,10 +638,22 @@ #define ENABLE_FTPDIR 1 #endif +#if !defined(ENABLE_CONTEXT_MENUS) +#define ENABLE_CONTEXT_MENUS 1 +#endif + +#if !defined(ENABLE_DRAG_SUPPORT) +#define ENABLE_DRAG_SUPPORT 1 +#endif + #if !defined(ENABLE_DASHBOARD_SUPPORT) #define ENABLE_DASHBOARD_SUPPORT 0 #endif +#if !defined(ENABLE_INSPECTOR) +#define ENABLE_INSPECTOR 1 +#endif + #if !defined(ENABLE_MAC_JAVA_BRIDGE) #define ENABLE_MAC_JAVA_BRIDGE 0 #endif @@ -629,6 +681,10 @@ #define ENABLE_GEOLOCATION 0 #endif +#if !defined(ENABLE_NOTIFICATIONS) +#define ENABLE_NOTIFICATIONS 0 +#endif + #if !defined(ENABLE_TEXT_CARET) #define ENABLE_TEXT_CARET 1 #endif @@ -637,9 +693,21 @@ #define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0 #endif -#if !defined(WTF_USE_ALTERNATE_JSIMMEDIATE) && PLATFORM(X86_64) && PLATFORM(MAC) -#define WTF_USE_ALTERNATE_JSIMMEDIATE 1 +#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) +#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX) || PLATFORM(SOLARIS) || PLATFORM(HPUX)) +#define WTF_USE_JSVALUE64 1 +#elif (PLATFORM(IA64) && !PLATFORM(IA64_32)) || PLATFORM(SPARC64) +#define WTF_USE_JSVALUE64 1 +#elif PLATFORM(ARM) || PLATFORM(PPC64) +#define WTF_USE_JSVALUE32 1 +#elif PLATFORM(WIN_OS) && COMPILER(MINGW) +/* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg +on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ +#define WTF_USE_JSVALUE32 1 +#else +#define WTF_USE_JSVALUE32_64 1 #endif +#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) */ #if !defined(ENABLE_REPAINT_THROTTLING) #define ENABLE_REPAINT_THROTTLING 0 @@ -654,7 +722,7 @@ #elif PLATFORM(X86) && PLATFORM(MAC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) +#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_OPTIMIZE_NATIVE_CALL 0 @@ -663,18 +731,23 @@ #define ENABLE_JIT 1 #endif -#if PLATFORM(X86) && PLATFORM(QT) -#if PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100 +#if PLATFORM(QT) +#if PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100 #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(WIN_OS) && COMPILER(MSVC) +#elif PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1 -#elif PLATFORM(LINUX) && GCC_VERSION >= 40100 +#elif PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100 #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) + #define ENABLE_JIT 1 + #if PLATFORM(ARM_THUMB2) + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 + #endif #endif -#endif /* PLATFORM(QT) && PLATFORM(X86) */ +#endif /* PLATFORM(QT) */ #endif /* !defined(ENABLE_JIT) */ @@ -688,9 +761,6 @@ #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 #endif -#ifndef ENABLE_JIT_OPTIMIZE_ARITHMETIC -#define ENABLE_JIT_OPTIMIZE_ARITHMETIC 1 -#endif #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 #endif @@ -721,16 +791,17 @@ #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_ARCH(7) && PLATFORM(IPHONE) && 0) \ + || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) && 0) \ || (PLATFORM(X86) && PLATFORM(WIN)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif -#if PLATFORM(X86) && PLATFORM(QT) -#if (PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ - || (PLATFORM(WIN_OS) && COMPILER(MSVC)) \ - || (PLATFORM(LINUX) && GCC_VERSION >= 40100) +#if PLATFORM(QT) +#if (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ + || (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC)) \ + || (PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100) \ + || (PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif @@ -748,7 +819,7 @@ #endif /* Setting this flag prevents the assembler from using RWX memory; this may improve security but currectly comes at a significant performance cost. */ -#if PLATFORM(ARM) +#if PLATFORM(IPHONE) #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1 #else #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0 @@ -758,10 +829,6 @@ #define ENABLE_PAN_SCROLLING 1 #endif -#if !defined(ENABLE_ACTIVEX_TYPE_CONVERSION_WMPLAYER) -#define ENABLE_ACTIVEX_TYPE_CONVERSION_WMPLAYER 1 -#endif - /* Use the QtXmlStreamReader implementation for XMLTokenizer */ #if PLATFORM(QT) #if !ENABLE(XSLT) @@ -784,4 +851,13 @@ #define WTF_USE_ACCELERATED_COMPOSITING 1 #endif +#if COMPILER(GCC) +#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result)) +#else +#define WARN_UNUSED_RETURN +#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 + #endif /* WTF_Platform_h */ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.d b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PossiblyNull.h index b9efaff..79c4d82 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.d +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PossiblyNull.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * 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 @@ -23,18 +23,37 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -provider JavaScriptCore -{ - probe gc__begin(); - probe gc__marked(); - probe gc__end(int, int); - - probe profile__will_execute(int, char*, char*, int); - probe profile__did_execute(int, char*, char*, int); +#ifndef PossiblyNull_h +#define PossiblyNull_h + +#include "Assertions.h" + +namespace WTF { + +template <typename T> struct PossiblyNull { + PossiblyNull(T data) + : m_data(data) + { + } + PossiblyNull(const PossiblyNull<T>& source) + : m_data(source.m_data) + { + source.m_data = 0; + } + ~PossiblyNull() { ASSERT(!m_data); } + bool getValue(T& out) WARN_UNUSED_RETURN; +private: + mutable T m_data; }; -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore provider -#pragma D attributes Private/Private/Unknown provider JavaScriptCore module -#pragma D attributes Private/Private/Unknown provider JavaScriptCore function -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore name -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore args +template <typename T> bool PossiblyNull<T>::getValue(T& out) +{ + out = m_data; + bool result = !!m_data; + m_data = 0; + return result; +} + +} + +#endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h index f4527df..5d0bd2a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h @@ -34,10 +34,8 @@ #include <wtf/Assertions.h> namespace WTF { - template<class T, typename FlagEnum> class PtrAndFlags { + template<class T, typename FlagEnum> class PtrAndFlagsBase { public: - PtrAndFlags() : m_ptrAndFlags(0) {} - bool isFlagSet(FlagEnum flagNumber) const { ASSERT(flagNumber < 2); return m_ptrAndFlags & (1 << flagNumber); } void setFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags |= (1 << flagNumber);} void clearFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags &= ~(1 << flagNumber);} @@ -51,14 +49,31 @@ namespace WTF { #endif } - private: + bool operator!() const { return !get(); } + T* operator->() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); } + + protected: intptr_t m_ptrAndFlags; #ifndef NDEBUG void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced. #endif }; + + template<class T, typename FlagEnum> class PtrAndFlags : public PtrAndFlagsBase<T, FlagEnum> { + public: + PtrAndFlags() + { + PtrAndFlagsBase<T, FlagEnum>::m_ptrAndFlags = 0; + } + PtrAndFlags(T* ptr) + { + PtrAndFlagsBase<T, FlagEnum>::m_ptrAndFlags = 0; + set(ptr); + } + }; } // namespace WTF +using WTF::PtrAndFlagsBase; using WTF::PtrAndFlags; #endif // PtrAndFlags_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h index 1c2d364..a66433e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h @@ -42,7 +42,6 @@ extern "C" { void init_by_array(unsigned long init_key[],int key_length); } -#include <ce_time.h> #endif // Internal JavaScriptCore usage only diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h index 74cd0ea..1a0b1fe 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h @@ -36,8 +36,8 @@ namespace WTF { template <typename T> class RefPtr : public FastAllocBase { public: RefPtr() : m_ptr(0) { } - RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); } - RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); } + RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } + RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); } // see comment in PassRefPtr.h for why this takes const reference template <typename U> RefPtr(const PassRefPtr<U>&); @@ -48,13 +48,13 @@ namespace WTF { RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } - ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); } + ~RefPtr() { T* ptr = m_ptr; derefIfNotNull(ptr); } - template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); } + template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(static_cast<T*>(o.get())) { if (T* ptr = static_cast<T*>(m_ptr)) ptr->ref(); } T* get() const { return m_ptr; } - void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; } + void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; } PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } T& operator*() const { return *m_ptr; } @@ -92,35 +92,29 @@ namespace WTF { template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o) { T* optr = o.get(); - if (optr) - optr->ref(); + refIfNotNull(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); - if (optr) - optr->ref(); + refIfNotNull(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) { - if (optr) - optr->ref(); + refIfNotNull(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } @@ -128,8 +122,7 @@ namespace WTF { { T* ptr = m_ptr; m_ptr = o.releaseRef(); - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } @@ -137,8 +130,7 @@ namespace WTF { { T* ptr = m_ptr; m_ptr = o.releaseRef(); - if (ptr) - ptr->deref(); + derefIfNotNull(ptr); return *this; } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtrHashMap.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtrHashMap.h index b3ccd3a..14684e8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtrHashMap.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtrHashMap.h @@ -42,7 +42,7 @@ namespace WTF { }; template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> - class RefPtrHashMap { + class RefPtrHashMap : public FastAllocBase { private: typedef KeyTraitsArg KeyTraits; typedef MappedTraitsArg MappedTraits; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/SegmentedVector.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/SegmentedVector.h index 065c19c..b1cbc4d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/SegmentedVector.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/SegmentedVector.h @@ -116,6 +116,7 @@ namespace WTF { } size_t size() const { return m_size; } + bool isEmpty() const { return !size(); } T& at(size_t index) { @@ -249,4 +250,6 @@ namespace WTF { } // namespace WTF +using WTF::SegmentedVector; + #endif // SegmentedVector_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h index afc5e8a..d21d1ff 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h @@ -41,6 +41,11 @@ static type& name = *new type arguments #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 +// NULL can cause compiler problems, especially in cases of multiple inheritance. +#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000) + namespace WTF { /* diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h index 1c23390..559e3f2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h @@ -85,4 +85,20 @@ inline int strcasecmp(const char* s1, const char* s2) #endif +#if PLATFORM(WIN_OS) || PLATFORM(LINUX) + +inline char* strnstr(const char* buffer, const char* target, size_t bufferLength) +{ + size_t targetLength = strlen(target); + if (targetLength == 0) + return const_cast<char*>(buffer); + for (const char* start = buffer; *start && start + targetLength <= buffer + bufferLength; start++) { + if (*start == *target && strncmp(start + 1, target + 1, targetLength - 1) == 0) + return const_cast<char*>(start); + } + return 0; +} + +#endif + #endif // WTF_StringExtras_h diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h index 74c02f3..ced2283 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h @@ -37,9 +37,7 @@ #include <time.h> /* For nanosleep() */ -#if !PLATFORM(WIN_OS) #include <sched.h> /* For sched_yield() */ -#endif #if HAVE(STDINT_H) #include <stdint.h> @@ -136,11 +134,7 @@ struct TCMalloc_SpinLock { #define SPINLOCK_INITIALIZER { 0 } static void TCMalloc_SlowLock(volatile unsigned int* lockword) { -#if !PLATFORM(WIN_OS) sched_yield(); // Yield immediately since fast path failed -#else - SwitchToThread(); -#endif while (true) { int r; #if COMPILER(GCC) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp index 478ce63..659bb0e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp @@ -31,6 +31,14 @@ // Author: Sanjay Ghemawat #include "config.h" +#include "TCSystemAlloc.h" + +#include <algorithm> +#include <fcntl.h> +#include "Assertions.h" +#include "TCSpinLock.h" +#include "UnusedParam.h" + #if HAVE(STDINT_H) #include <stdint.h> #elif HAVE(INTTYPES_H) @@ -38,6 +46,7 @@ #else #include <sys/types.h> #endif + #if PLATFORM(WIN_OS) #include "windows.h" #else @@ -45,16 +54,13 @@ #include <unistd.h> #include <sys/mman.h> #endif -#include <fcntl.h> -#include "Assertions.h" -#include "TCSystemAlloc.h" -#include "TCSpinLock.h" -#include "UnusedParam.h" #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON #endif +using namespace std; + // Structure for discovering alignment union MemoryAligner { void* p; @@ -441,6 +447,32 @@ void TCMalloc_SystemRelease(void* start, size_t length) ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED)); } +#elif HAVE(VIRTUALALLOC) + +void TCMalloc_SystemRelease(void* start, size_t length) +{ + if (VirtualFree(start, length, MEM_DECOMMIT)) + return; + + // The decommit may fail if the memory region consists of allocations + // from more than one call to VirtualAlloc. In this case, fall back to + // using VirtualQuery to retrieve the allocation boundaries and decommit + // them each individually. + + char* ptr = static_cast<char*>(start); + char* end = ptr + length; + MEMORY_BASIC_INFORMATION info; + while (ptr < end) { + size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); + ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); + + size_t decommitSize = min<size_t>(info.RegionSize, end - ptr); + BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT); + ASSERT_UNUSED(success, success); + ptr += decommitSize; + } +} + #else // Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease @@ -457,8 +489,28 @@ void TCMalloc_SystemCommit(void* start, size_t length) #elif HAVE(VIRTUALALLOC) -void TCMalloc_SystemCommit(void*, size_t) +void TCMalloc_SystemCommit(void* start, size_t length) { + if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start) + return; + + // The commit may fail if the memory region consists of allocations + // from more than one call to VirtualAlloc. In this case, fall back to + // using VirtualQuery to retrieve the allocation boundaries and commit them + // each individually. + + char* ptr = static_cast<char*>(start); + char* end = ptr + length; + MEMORY_BASIC_INFORMATION info; + while (ptr < end) { + size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); + ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); + + size_t commitSize = min<size_t>(info.RegionSize, end - ptr); + void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT, PAGE_READWRITE); + ASSERT_UNUSED(newAddress, newAddress == ptr); + ptr += commitSize; + } } #else diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.h index 8e3a01a..1c67788 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.h @@ -64,7 +64,7 @@ extern void TCMalloc_SystemRelease(void* start, size_t length); extern void TCMalloc_SystemCommit(void* start, size_t length); -#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) +#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) && !HAVE(VIRTUALALLOC) inline void TCMalloc_SystemRelease(void*, size_t) { } #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h index 4d5d2f7..b6f5fd3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h @@ -79,10 +79,13 @@ private: #if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(WIN_OS) struct Data : Noncopyable { Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} +#if PLATFORM(QT) + ~Data() { owner->destroy(this); } +#endif T* value; ThreadSpecific<T>* owner; -#if !USE(PTHREADS) +#if !USE(PTHREADS) && !PLATFORM(QT) void (*destructor)(void*); #endif }; @@ -136,9 +139,7 @@ inline ThreadSpecific<T>::ThreadSpecific() template<typename T> inline ThreadSpecific<T>::~ThreadSpecific() { - Data* data = static_cast<Data*>(m_key.localData()); - if (data) - data->destructor(data); + // Does not invoke destructor functions. QThreadStorage will do it } template<typename T> @@ -153,7 +154,6 @@ inline void ThreadSpecific<T>::set(T* ptr) { ASSERT(!get()); Data* data = new Data(ptr, this); - data->destructor = &ThreadSpecific<T>::destroy; m_key.setLocalData(data); } @@ -218,21 +218,27 @@ inline void ThreadSpecific<T>::destroy(void* ptr) // Some pthreads implementations zero out the pointer before calling destroy(), so we temporarily reset it. pthread_setspecific(data->owner->m_key, ptr); #endif - +#if PLATFORM(QT) + // See comment as above + data->owner->m_key.setLocalData(data); +#endif + data->value->~T(); fastFree(data->value); #if USE(PTHREADS) pthread_setspecific(data->owner->m_key, 0); #elif PLATFORM(QT) - data->owner->m_key.setLocalData(0); + // Do nothing here #elif PLATFORM(WIN_OS) TlsSetValue(tlsKeys()[data->owner->m_index], 0); #else #error ThreadSpecific is not implemented for this platform. #endif +#if !PLATFORM(QT) delete data; +#endif } template<typename T> diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h index 6578151..5154545 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h @@ -59,6 +59,8 @@ #ifndef Threading_h #define Threading_h +#include "Platform.h" + #if PLATFORM(WINCE) #include <windows.h> #endif @@ -213,23 +215,23 @@ private: #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 #if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE) -inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); } +inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); } inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); } #else -inline void atomicIncrement(int volatile* addend) { InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); } +inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); } inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); } #endif #elif PLATFORM(DARWIN) #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 -inline void atomicIncrement(int volatile* addend) { OSAtomicIncrement32Barrier(const_cast<int*>(addend)); } +inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); } inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); } -#elif COMPILER(GCC) +#elif COMPILER(GCC) && !PLATFORM(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 -inline void atomicIncrement(int volatile* addend) { __gnu_cxx::__atomic_add(addend, 1); } +inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; } #endif @@ -323,6 +325,11 @@ using WTF::ThreadCondition; using WTF::ThreadIdentifier; using WTF::ThreadSafeShared; +#if USE(LOCKFREE_THREADSAFESHARED) +using WTF::atomicDecrement; +using WTF::atomicIncrement; +#endif + using WTF::createThread; using WTF::currentThread; using WTF::isMainThread; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp index d0e6df8..c241bd9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -39,8 +39,11 @@ #include "StdLibExtras.h" #include "UnusedParam.h" #include <errno.h> + +#if !COMPILER(MSVC) #include <limits.h> #include <sys/time.h> +#endif #if PLATFORM(ANDROID) #include "jni_utility.h" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h index 7974b9a..eb4c279 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h @@ -21,6 +21,7 @@ #ifndef WTF_VectorTraits_h #define WTF_VectorTraits_h +#include "OwnPtr.h" #include "RefPtr.h" #include "TypeTraits.h" #include <utility> @@ -71,11 +72,14 @@ namespace WTF { static const bool canCompareWithMemcmp = true; }; - // we know RefPtr is simple enough that initializing to 0 and moving with memcpy + // we know OwnPtr and RefPtr are simple enough that initializing to 0 and moving with memcpy // (and then not destructing the original) will totally work template<typename P> struct VectorTraits<RefPtr<P> > : SimpleClassVectorTraits { }; - + + template<typename P> + struct VectorTraits<OwnPtr<P> > : SimpleClassVectorTraits { }; + template<typename P> struct VectorTraits<std::auto_ptr<P> > : SimpleClassVectorTraits { }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h index f86a9b7..7016a03 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 George Staikos <staikos@kde.org> * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,11 +26,17 @@ #include <wtf/Assertions.h> #if USE(QT4_UNICODE) +#if COMPILER(WINSCW) || COMPILER(RVCT) +#include "wtf/unicode/qt4/UnicodeQt4.h" +#else #include "qt4/UnicodeQt4.h" +#endif #elif USE(ICU_UNICODE) #include <wtf/unicode/icu/UnicodeIcu.h> #elif USE(GLIB_UNICODE) #include <wtf/unicode/glib/UnicodeGLib.h> +#elif USE(WINCE_UNICODE) +#include <wtf/unicode/wince/UnicodeWince.h> #else #error "Unknown Unicode implementation" #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h index 65b3e79..e01f825 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h @@ -58,7 +58,7 @@ QT_END_NAMESPACE #endif // ugly hack to make UChar compatible with JSChar in API/JSStringRef.h -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) || COMPILER(WINSCW) typedef wchar_t UChar; #else typedef uint16_t UChar; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp new file mode 100644 index 0000000..966f2a1 --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "UnicodeWince.h" + +#include <wchar.h> + +namespace WTF { +namespace Unicode { + +wchar_t toLower(wchar_t c) +{ + return towlower(c); +} + +wchar_t toUpper(wchar_t c) +{ + return towupper(c); +} + +wchar_t foldCase(wchar_t c) +{ + return towlower(c); +} + +bool isPrintableChar(wchar_t c) +{ + return !!iswprint(c); +} + +bool isSpace(wchar_t c) +{ + return !!iswspace(c); +} + +bool isLetter(wchar_t c) +{ + return !!iswalpha(c); +} + +bool isUpper(wchar_t c) +{ + return !!iswupper(c); +} + +bool isLower(wchar_t c) +{ + return !!iswlower(c); +} + +bool isDigit(wchar_t c) +{ + return !!iswdigit(c); +} + +bool isPunct(wchar_t c) +{ + return !!iswpunct(c); +} + +int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + int remainingCharacters = 0; + if (sourceLength <= resultLength) + while (sourceIterator < sourceEnd) + *resultIterator++ = towlower(*sourceIterator++); + else + while (resultIterator < resultEnd) + *resultIterator++ = towlower(*sourceIterator++); + + if (sourceIterator < sourceEnd) + remainingCharacters += sourceEnd - sourceIterator; + *isError = (remainingCharacters != 0); + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + int remainingCharacters = 0; + if (sourceLength <= resultLength) + while (sourceIterator < sourceEnd) + *resultIterator++ = towupper(*sourceIterator++); + else + while (resultIterator < resultEnd) + *resultIterator++ = towupper(*sourceIterator++); + + if (sourceIterator < sourceEnd) + remainingCharacters += sourceEnd - sourceIterator; + *isError = (remainingCharacters != 0); + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + *isError = false; + if (resultLength < sourceLength) { + *isError = true; + return sourceLength; + } + for (int i = 0; i < sourceLength; ++i) + result[i] = foldCase(source[i]); + return sourceLength; +} + +wchar_t toTitleCase(wchar_t c) +{ + return towupper(c); +} + +Direction direction(UChar32 c) +{ + return static_cast<Direction>(UnicodeCE::direction(c)); +} + +CharCategory category(unsigned int c) +{ + return static_cast<CharCategory>(TO_MASK((__int8) UnicodeCE::category(c))); +} + +DecompositionType decompositionType(UChar32 c) +{ + return static_cast<DecompositionType>(UnicodeCE::decompositionType(c)); +} + +unsigned char combiningClass(UChar32 c) +{ + return UnicodeCE::combiningClass(c); +} + +wchar_t mirroredChar(UChar32 c) +{ + return UnicodeCE::mirroredChar(c); +} + +int digitValue(wchar_t c) +{ + return UnicodeCE::digitValue(c); +} + +} // namespace Unicode +} // namespace WTF diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h new file mode 100644 index 0000000..db656ec --- /dev/null +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> + * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef UNICODE_WINCE_H +#define UNICODE_WINCE_H + +#include "ce_unicode.h" + +#define TO_MASK(x) (1 << (x)) + +// some defines from ICU needed one or two places + +#define U16_IS_LEAD(c) (((c) & 0xfffffc00) == 0xd800) +#define U16_IS_TRAIL(c) (((c) & 0xfffffc00) == 0xdc00) +#define U16_SURROGATE_OFFSET ((0xd800 << 10UL) + 0xdc00 - 0x10000) +#define U16_GET_SUPPLEMENTARY(lead, trail) \ + (((UChar32)(lead) << 10UL) + (UChar32)(trail) - U16_SURROGATE_OFFSET) + +#define U16_LEAD(supplementary) (UChar)(((supplementary) >> 10) + 0xd7c0) +#define U16_TRAIL(supplementary) (UChar)(((supplementary) & 0x3ff) | 0xdc00) + +#define U_IS_SURROGATE(c) (((c) & 0xfffff800) == 0xd800) +#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c) +#define U16_IS_SURROGATE_LEAD(c) (((c) & 0x400) == 0) + +#define U16_NEXT(s, i, length, c) { \ + (c)=(s)[(i)++]; \ + if (U16_IS_LEAD(c)) { \ + uint16_t __c2; \ + if ((i) < (length) && U16_IS_TRAIL(__c2 = (s)[(i)])) { \ + ++(i); \ + (c) = U16_GET_SUPPLEMENTARY((c), __c2); \ + } \ + } \ +} + +#define U16_PREV(s, start, i, c) { \ + (c)=(s)[--(i)]; \ + if (U16_IS_TRAIL(c)) { \ + uint16_t __c2; \ + if ((i) > (start) && U16_IS_LEAD(__c2 = (s)[(i) - 1])) { \ + --(i); \ + (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } \ + } \ +} + +#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c) + +namespace WTF { + + namespace Unicode { + + enum Direction { + LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT, + RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT, + EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER, + EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR, + EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR, + ArabicNumber = UnicodeCE::U_ARABIC_NUMBER, + CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR, + BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR, + SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR, + WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL, + OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL, + LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING, + LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE, + RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC, + RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING, + RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE, + PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT, + NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK, + BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL + }; + + enum DecompositionType { + DecompositionNone = UnicodeCE::U_DT_NONE, + DecompositionCanonical = UnicodeCE::U_DT_CANONICAL, + DecompositionCompat = UnicodeCE::U_DT_COMPAT, + DecompositionCircle = UnicodeCE::U_DT_CIRCLE, + DecompositionFinal = UnicodeCE::U_DT_FINAL, + DecompositionFont = UnicodeCE::U_DT_FONT, + DecompositionFraction = UnicodeCE::U_DT_FRACTION, + DecompositionInitial = UnicodeCE::U_DT_INITIAL, + DecompositionIsolated = UnicodeCE::U_DT_ISOLATED, + DecompositionMedial = UnicodeCE::U_DT_MEDIAL, + DecompositionNarrow = UnicodeCE::U_DT_NARROW, + DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK, + DecompositionSmall = UnicodeCE::U_DT_SMALL, + DecompositionSquare = UnicodeCE::U_DT_SQUARE, + DecompositionSub = UnicodeCE::U_DT_SUB, + DecompositionSuper = UnicodeCE::U_DT_SUPER, + DecompositionVertical = UnicodeCE::U_DT_VERTICAL, + DecompositionWide = UnicodeCE::U_DT_WIDE, + }; + + enum CharCategory { + NoCategory = 0, + Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES), + Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER), + Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER), + Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER), + Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER), + Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER), + + Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK), + Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK), + Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK), + + Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER), + Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER), + Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER), + + Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR), + Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR), + Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR), + + Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR), + Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR), + Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR), + Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE), + + Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION), + Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION), + Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION), + Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION), + Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION), + + Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL), + Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL), + Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL), + Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL), + + Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION), + Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION) + }; + + CharCategory category(unsigned int); + + bool isSpace(wchar_t); + bool isLetter(wchar_t); + bool isPrintableChar(wchar_t); + bool isUpper(wchar_t); + bool isLower(wchar_t); + bool isPunct(wchar_t); + bool isDigit(wchar_t); + inline bool isSeparatorSpace(wchar_t c) { return category(c) == Separator_Space; } + inline bool isHighSurrogate(wchar_t c) { return (c & 0xfc00) == 0xd800; } + inline bool isLowSurrogate(wchar_t c) { return (c & 0xfc00) == 0xdc00; } + + wchar_t toLower(wchar_t); + wchar_t toUpper(wchar_t); + wchar_t foldCase(wchar_t); + wchar_t toTitleCase(wchar_t); + int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + int foldCase(UChar* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + + int digitValue(wchar_t); + + wchar_t mirroredChar(UChar32); + unsigned char combiningClass(UChar32); + DecompositionType decompositionType(UChar32); + Direction direction(UChar32); + inline bool isArabicChar(UChar32) + { + return false; // FIXME: implement! + } + + inline bool hasLineBreakingPropertyComplexContext(UChar32) + { + return false; // FIXME: implement! + } + + inline int umemcasecmp(const wchar_t* a, const wchar_t* b, int len) + { + for (int i = 0; i < len; ++i) { + wchar_t c1 = foldCase(a[i]); + wchar_t c2 = foldCase(b[i]); + if (c1 != c2) + return c1 - c2; + } + return 0; + } + + inline UChar32 surrogateToUcs4(wchar_t high, wchar_t low) + { + return (UChar32(high) << 10) + low - 0x35fdc00; + } + + } // namespace Unicode + +} // namespace WTF + +#endif +// vim: ts=2 sw=2 et diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp index b0aae65..aafea3c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -20,7 +20,7 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -90,7 +90,7 @@ public: : term(0) { } - + void* operator new(size_t, void* where) { return where; @@ -124,7 +124,7 @@ public: subpatternBackup[i] = output[(firstSubpatternId << 1) + i]; output[(firstSubpatternId << 1) + i] = -1; } - + new(getDisjunctionContext(term)) DisjunctionContext(); } @@ -138,7 +138,7 @@ public: for (unsigned i = 0; i < (numNestedSubpatterns << 1); ++i) output[(firstSubpatternId << 1) + i] = subpatternBackup[i]; } - + DisjunctionContext* getDisjunctionContext(ByteTerm& term) { return reinterpret_cast<DisjunctionContext*>(&(subpatternBackup[term.atom.parenthesesDisjunction->m_numSubpatterns << 1])); @@ -208,7 +208,7 @@ public: return input[pos - 1]; return -1; } - + unsigned getPos() { return pos; @@ -218,7 +218,7 @@ public: { pos = p; } - + bool atStart() { return pos == 0; @@ -284,7 +284,7 @@ public: { if (input.atEnd()) return false; - + int ch = input.read(); if (pattern->m_ignoreCase ? ((Unicode::toLower(testChar) == ch) || (Unicode::toUpper(testChar) == ch)) : (testChar == ch)) { @@ -341,7 +341,7 @@ public: return false; } } - + return true; } @@ -606,10 +606,10 @@ public: if (matchDisjunction(term.atom.parenthesesDisjunction, context->getDisjunctionContext(term), true)) return true; - + resetMatches(term, context); - freeParenthesesDisjunctionContext(context); popParenthesesDisjunctionContext(backTrack); + freeParenthesesDisjunctionContext(context); } return false; @@ -910,8 +910,8 @@ public: } } else { resetMatches(term, context); - freeParenthesesDisjunctionContext(context); popParenthesesDisjunctionContext(backTrack); + freeParenthesesDisjunctionContext(context); } if (backTrack->matchAmount) { @@ -946,11 +946,11 @@ public: } return true; } - + // pop a match off the stack resetMatches(term, context); - freeParenthesesDisjunctionContext(context); popParenthesesDisjunctionContext(backTrack); + freeParenthesesDisjunctionContext(context); } return false; @@ -1266,37 +1266,37 @@ public: ByteCompiler(RegexPattern& pattern) : m_pattern(pattern) { - bodyDisjunction = 0; - currentAlternativeIndex = 0; + m_bodyDisjunction = 0; + m_currentAlternativeIndex = 0; } - + BytecodePattern* compile() { regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize); emitDisjunction(m_pattern.m_body); regexEnd(); - return new BytecodePattern(bodyDisjunction, m_allParenthesesInfo, m_pattern); + return new BytecodePattern(m_bodyDisjunction, m_allParenthesesInfo, m_pattern); } - + void checkInput(unsigned count) { - bodyDisjunction->terms.append(ByteTerm::CheckInput(count)); + m_bodyDisjunction->terms.append(ByteTerm::CheckInput(count)); } void assertionBOL(int inputPosition) { - bodyDisjunction->terms.append(ByteTerm::BOL(inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm::BOL(inputPosition)); } void assertionEOL(int inputPosition) { - bodyDisjunction->terms.append(ByteTerm::EOL(inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm::EOL(inputPosition)); } void assertionWordBoundary(bool invert, int inputPosition) { - bodyDisjunction->terms.append(ByteTerm::WordBoundary(invert, inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm::WordBoundary(invert, inputPosition)); } void atomPatternCharacter(UChar ch, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType) @@ -1304,60 +1304,60 @@ public: if (m_pattern.m_ignoreCase) { UChar lo = Unicode::toLower(ch); UChar hi = Unicode::toUpper(ch); - + if (lo != hi) { - bodyDisjunction->terms.append(ByteTerm(lo, hi, inputPosition, frameLocation, quantityCount, quantityType)); + m_bodyDisjunction->terms.append(ByteTerm(lo, hi, inputPosition, frameLocation, quantityCount, quantityType)); return; } } - bodyDisjunction->terms.append(ByteTerm(ch, inputPosition, frameLocation, quantityCount, quantityType)); + m_bodyDisjunction->terms.append(ByteTerm(ch, inputPosition, frameLocation, quantityCount, quantityType)); } - + void atomCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType) { - bodyDisjunction->terms.append(ByteTerm(characterClass, invert, inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm(characterClass, invert, inputPosition)); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount; - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType; - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; } void atomBackReference(unsigned subpatternId, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType) { ASSERT(subpatternId); - bodyDisjunction->terms.append(ByteTerm::BackReference(subpatternId, inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm::BackReference(subpatternId, inputPosition)); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount; - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType; - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType; + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; } void atomParenthesesSubpatternBegin(unsigned subpatternId, bool capture, int inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation) { - int beginTerm = bodyDisjunction->terms.size(); + int beginTerm = m_bodyDisjunction->terms.size(); - bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, inputPosition)); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; - bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation; + m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, inputPosition)); + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; + m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation; - m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, currentAlternativeIndex)); - currentAlternativeIndex = beginTerm + 1; + m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, m_currentAlternativeIndex)); + m_currentAlternativeIndex = beginTerm + 1; } void atomParentheticalAssertionBegin(unsigned subpatternId, bool invert, unsigned frameLocation, unsigned alternativeFrameLocation) { - int beginTerm = bodyDisjunction->terms.size(); + int beginTerm = m_bodyDisjunction->terms.size(); - bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionBegin, subpatternId, invert, 0)); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; - bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); - bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation; + m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionBegin, subpatternId, invert, 0)); + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; + m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); + m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation; - m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, currentAlternativeIndex)); - currentAlternativeIndex = beginTerm + 1; + m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, m_currentAlternativeIndex)); + m_currentAlternativeIndex = beginTerm + 1; } unsigned popParenthesesStack() @@ -1365,12 +1365,12 @@ public: ASSERT(m_parenthesesStack.size()); int stackEnd = m_parenthesesStack.size() - 1; unsigned beginTerm = m_parenthesesStack[stackEnd].beginTerm; - currentAlternativeIndex = m_parenthesesStack[stackEnd].savedAlternativeIndex; + m_currentAlternativeIndex = m_parenthesesStack[stackEnd].savedAlternativeIndex; m_parenthesesStack.shrink(stackEnd); - ASSERT(beginTerm < bodyDisjunction->terms.size()); - ASSERT(currentAlternativeIndex < bodyDisjunction->terms.size()); - + ASSERT(beginTerm < m_bodyDisjunction->terms.size()); + ASSERT(m_currentAlternativeIndex < m_bodyDisjunction->terms.size()); + return beginTerm; } @@ -1387,25 +1387,25 @@ public: void closeAlternative(int beginTerm) { int origBeginTerm = beginTerm; - ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeBegin); - int endIndex = bodyDisjunction->terms.size(); + ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeBegin); + int endIndex = m_bodyDisjunction->terms.size(); - unsigned frameLocation = bodyDisjunction->terms[beginTerm].frameLocation; + unsigned frameLocation = m_bodyDisjunction->terms[beginTerm].frameLocation; - if (!bodyDisjunction->terms[beginTerm].alternative.next) - bodyDisjunction->terms.remove(beginTerm); + if (!m_bodyDisjunction->terms[beginTerm].alternative.next) + m_bodyDisjunction->terms.remove(beginTerm); else { - while (bodyDisjunction->terms[beginTerm].alternative.next) { - beginTerm += bodyDisjunction->terms[beginTerm].alternative.next; - ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeDisjunction); - bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm; - bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; + while (m_bodyDisjunction->terms[beginTerm].alternative.next) { + beginTerm += m_bodyDisjunction->terms[beginTerm].alternative.next; + ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeDisjunction); + m_bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm; + m_bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; } - - bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm; - bodyDisjunction->terms.append(ByteTerm::AlternativeEnd()); - bodyDisjunction->terms[endIndex].frameLocation = frameLocation; + m_bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm; + + m_bodyDisjunction->terms.append(ByteTerm::AlternativeEnd()); + m_bodyDisjunction->terms[endIndex].frameLocation = frameLocation; } } @@ -1413,46 +1413,46 @@ public: { int beginTerm = 0; int origBeginTerm = 0; - ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeBegin); - int endIndex = bodyDisjunction->terms.size(); + ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeBegin); + int endIndex = m_bodyDisjunction->terms.size(); - unsigned frameLocation = bodyDisjunction->terms[beginTerm].frameLocation; + unsigned frameLocation = m_bodyDisjunction->terms[beginTerm].frameLocation; - while (bodyDisjunction->terms[beginTerm].alternative.next) { - beginTerm += bodyDisjunction->terms[beginTerm].alternative.next; - ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeDisjunction); - bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm; - bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; + while (m_bodyDisjunction->terms[beginTerm].alternative.next) { + beginTerm += m_bodyDisjunction->terms[beginTerm].alternative.next; + ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeDisjunction); + m_bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm; + m_bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; } - - bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm; - bodyDisjunction->terms.append(ByteTerm::BodyAlternativeEnd()); - bodyDisjunction->terms[endIndex].frameLocation = frameLocation; + m_bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm; + + m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeEnd()); + m_bodyDisjunction->terms[endIndex].frameLocation = frameLocation; } void atomParenthesesEnd(bool doInline, unsigned lastSubpatternId, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType, unsigned callFrameSize = 0) { unsigned beginTerm = popParenthesesStack(); closeAlternative(beginTerm + 1); - unsigned endTerm = bodyDisjunction->terms.size(); + unsigned endTerm = m_bodyDisjunction->terms.size(); - bool isAssertion = bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParentheticalAssertionBegin; - bool invertOrCapture = bodyDisjunction->terms[beginTerm].invertOrCapture; - unsigned subpatternId = bodyDisjunction->terms[beginTerm].atom.subpatternId; + bool isAssertion = m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParentheticalAssertionBegin; + bool invertOrCapture = m_bodyDisjunction->terms[beginTerm].invertOrCapture; + unsigned subpatternId = m_bodyDisjunction->terms[beginTerm].atom.subpatternId; - bodyDisjunction->terms.append(ByteTerm(isAssertion ? ByteTerm::TypeParentheticalAssertionEnd : ByteTerm::TypeParenthesesSubpatternOnceEnd, subpatternId, invertOrCapture, inputPosition)); - bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm; - bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm; - bodyDisjunction->terms[endTerm].frameLocation = frameLocation; + m_bodyDisjunction->terms.append(ByteTerm(isAssertion ? ByteTerm::TypeParentheticalAssertionEnd : ByteTerm::TypeParenthesesSubpatternOnceEnd, subpatternId, invertOrCapture, inputPosition)); + m_bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm; + m_bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm; + m_bodyDisjunction->terms[endTerm].frameLocation = frameLocation; if (doInline) { - bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount; - bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType; - bodyDisjunction->terms[endTerm].atom.quantityCount = quantityCount; - bodyDisjunction->terms[endTerm].atom.quantityType = quantityType; + m_bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount; + m_bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType; + m_bodyDisjunction->terms[endTerm].atom.quantityCount = quantityCount; + m_bodyDisjunction->terms[endTerm].atom.quantityType = quantityType; } else { - ByteTerm& parenthesesBegin = bodyDisjunction->terms[beginTerm]; + ByteTerm& parenthesesBegin = m_bodyDisjunction->terms[beginTerm]; ASSERT(parenthesesBegin.type == ByteTerm::TypeParenthesesSubpatternOnceBegin); bool invertOrCapture = parenthesesBegin.invertOrCapture; @@ -1463,26 +1463,26 @@ public: parenthesesDisjunction->terms.append(ByteTerm::SubpatternBegin()); for (unsigned termInParentheses = beginTerm + 1; termInParentheses < endTerm; ++termInParentheses) - parenthesesDisjunction->terms.append(bodyDisjunction->terms[termInParentheses]); + parenthesesDisjunction->terms.append(m_bodyDisjunction->terms[termInParentheses]); parenthesesDisjunction->terms.append(ByteTerm::SubpatternEnd()); - bodyDisjunction->terms.shrink(beginTerm); + m_bodyDisjunction->terms.shrink(beginTerm); m_allParenthesesInfo.append(parenthesesDisjunction); - bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, invertOrCapture, inputPosition)); + m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, invertOrCapture, inputPosition)); - bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount; - bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType; - bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; + m_bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount; + m_bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType; + m_bodyDisjunction->terms[beginTerm].frameLocation = frameLocation; } } void regexBegin(unsigned numSubpatterns, unsigned callFrameSize) { - bodyDisjunction = new ByteDisjunction(numSubpatterns, callFrameSize); - bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin()); - bodyDisjunction->terms[0].frameLocation = 0; - currentAlternativeIndex = 0; + m_bodyDisjunction = new ByteDisjunction(numSubpatterns, callFrameSize); + m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin()); + m_bodyDisjunction->terms[0].frameLocation = 0; + m_currentAlternativeIndex = 0; } void regexEnd() @@ -1492,27 +1492,27 @@ public: void alterantiveBodyDisjunction() { - int newAlternativeIndex = bodyDisjunction->terms.size(); - bodyDisjunction->terms[currentAlternativeIndex].alternative.next = newAlternativeIndex - currentAlternativeIndex; - bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction()); + int newAlternativeIndex = m_bodyDisjunction->terms.size(); + m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; + m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction()); - currentAlternativeIndex = newAlternativeIndex; + m_currentAlternativeIndex = newAlternativeIndex; } void alterantiveDisjunction() { - int newAlternativeIndex = bodyDisjunction->terms.size(); - bodyDisjunction->terms[currentAlternativeIndex].alternative.next = newAlternativeIndex - currentAlternativeIndex; - bodyDisjunction->terms.append(ByteTerm::AlternativeDisjunction()); + int newAlternativeIndex = m_bodyDisjunction->terms.size(); + m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; + m_bodyDisjunction->terms.append(ByteTerm::AlternativeDisjunction()); - currentAlternativeIndex = newAlternativeIndex; + m_currentAlternativeIndex = newAlternativeIndex; } void emitDisjunction(PatternDisjunction* disjunction, unsigned inputCountAlreadyChecked = 0, unsigned parenthesesInputCountAlreadyChecked = 0) { for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) { unsigned currentCountAlreadyChecked = inputCountAlreadyChecked; - + if (alt) { if (disjunction == m_pattern.m_body) alterantiveBodyDisjunction(); @@ -1586,7 +1586,7 @@ public: case PatternTerm::TypeParentheticalAssertion: { unsigned alternativeFrameLocation = term.inputPosition + RegexStackSpaceForBackTrackInfoParentheticalAssertion; - + atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation); emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0); atomParenthesesEnd(true, term.parentheses.lastSubpatternId, 0, term.frameLocation, term.quantityCount, term.quantityType); @@ -1599,8 +1599,8 @@ public: private: RegexPattern& m_pattern; - ByteDisjunction* bodyDisjunction; - unsigned currentAlternativeIndex; + ByteDisjunction* m_bodyDisjunction; + unsigned m_currentAlternativeIndex; Vector<ParenthesesStackEntry> m_parenthesesStack; Vector<ByteDisjunction*> m_allParenthesesInfo; }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.h b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.h index a8c122a..48c9a5e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.h @@ -280,7 +280,7 @@ struct ByteTerm { } }; -class ByteDisjunction { +class ByteDisjunction : public FastAllocBase { public: ByteDisjunction(unsigned numSubpatterns, unsigned frameSize) : m_numSubpatterns(numSubpatterns) @@ -293,7 +293,7 @@ public: unsigned m_frameSize; }; -struct BytecodePattern { +struct BytecodePattern : FastAllocBase { BytecodePattern(ByteDisjunction* body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern) : m_body(body) , m_ignoreCase(pattern.m_ignoreCase) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp index 663a524..4390b5b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp @@ -45,35 +45,35 @@ class RegexGenerator : private MacroAssembler { friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline); #if PLATFORM(ARM) - static const RegisterID input = ARM::r0; - static const RegisterID index = ARM::r1; - static const RegisterID length = ARM::r2; - static const RegisterID output = ARM::r4; + static const RegisterID input = ARMRegisters::r0; + static const RegisterID index = ARMRegisters::r1; + static const RegisterID length = ARMRegisters::r2; + static const RegisterID output = ARMRegisters::r4; - static const RegisterID regT0 = ARM::r5; - static const RegisterID regT1 = ARM::r6; + static const RegisterID regT0 = ARMRegisters::r5; + static const RegisterID regT1 = ARMRegisters::r6; - static const RegisterID returnRegister = ARM::r0; + static const RegisterID returnRegister = ARMRegisters::r0; #elif PLATFORM(X86) - static const RegisterID input = X86::eax; - static const RegisterID index = X86::edx; - static const RegisterID length = X86::ecx; - static const RegisterID output = X86::edi; + static const RegisterID input = X86Registers::eax; + static const RegisterID index = X86Registers::edx; + static const RegisterID length = X86Registers::ecx; + static const RegisterID output = X86Registers::edi; - static const RegisterID regT0 = X86::ebx; - static const RegisterID regT1 = X86::esi; + static const RegisterID regT0 = X86Registers::ebx; + static const RegisterID regT1 = X86Registers::esi; - static const RegisterID returnRegister = X86::eax; + static const RegisterID returnRegister = X86Registers::eax; #elif PLATFORM(X86_64) - static const RegisterID input = X86::edi; - static const RegisterID index = X86::esi; - static const RegisterID length = X86::edx; - static const RegisterID output = X86::ecx; + static const RegisterID input = X86Registers::edi; + static const RegisterID index = X86Registers::esi; + static const RegisterID length = X86Registers::edx; + static const RegisterID output = X86Registers::ecx; - static const RegisterID regT0 = X86::eax; - static const RegisterID regT1 = X86::ebx; + static const RegisterID regT0 = X86Registers::eax; + static const RegisterID regT1 = X86Registers::ebx; - static const RegisterID returnRegister = X86::eax; + static const RegisterID returnRegister = X86Registers::eax; #endif void optimizeAlternative(PatternAlternative* alternative) @@ -1289,50 +1289,50 @@ class RegexGenerator : private MacroAssembler { void generateEnter() { #if PLATFORM(X86_64) - push(X86::ebp); - move(stackPointerRegister, X86::ebp); - push(X86::ebx); + push(X86Registers::ebp); + move(stackPointerRegister, X86Registers::ebp); + push(X86Registers::ebx); #elif PLATFORM(X86) - push(X86::ebp); - move(stackPointerRegister, X86::ebp); + push(X86Registers::ebp); + move(stackPointerRegister, X86Registers::ebp); // TODO: do we need spill registers to fill the output pointer if there are no sub captures? - push(X86::ebx); - push(X86::edi); - push(X86::esi); + push(X86Registers::ebx); + push(X86Registers::edi); + push(X86Registers::esi); // load output into edi (2 = saved ebp + return address). #if COMPILER(MSVC) - loadPtr(Address(X86::ebp, 2 * sizeof(void*)), input); - loadPtr(Address(X86::ebp, 3 * sizeof(void*)), index); - loadPtr(Address(X86::ebp, 4 * sizeof(void*)), length); - loadPtr(Address(X86::ebp, 5 * sizeof(void*)), output); + loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), input); + loadPtr(Address(X86Registers::ebp, 3 * sizeof(void*)), index); + loadPtr(Address(X86Registers::ebp, 4 * sizeof(void*)), length); + loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output); #else - loadPtr(Address(X86::ebp, 2 * sizeof(void*)), output); + loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif #elif PLATFORM(ARM) -#if !PLATFORM_ARM_ARCH(7) - push(ARM::lr); +#if PLATFORM(ARM_TRADITIONAL) + push(ARMRegisters::lr); #endif - push(ARM::r4); - push(ARM::r5); - push(ARM::r6); - move(ARM::r3, output); + push(ARMRegisters::r4); + push(ARMRegisters::r5); + push(ARMRegisters::r6); + move(ARMRegisters::r3, output); #endif } void generateReturn() { #if PLATFORM(X86_64) - pop(X86::ebx); - pop(X86::ebp); + pop(X86Registers::ebx); + pop(X86Registers::ebp); #elif PLATFORM(X86) - pop(X86::esi); - pop(X86::edi); - pop(X86::ebx); - pop(X86::ebp); + pop(X86Registers::esi); + pop(X86Registers::edi); + pop(X86Registers::ebx); + pop(X86Registers::ebp); #elif PLATFORM(ARM) - pop(ARM::r6); - pop(ARM::r5); - pop(ARM::r4); + pop(ARMRegisters::r6); + pop(ARMRegisters::r5); + pop(ARMRegisters::r4); #endif ret(); } diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION new file mode 100644 index 0000000..6160986 --- /dev/null +++ b/src/3rdparty/javascriptcore/VERSION @@ -0,0 +1,11 @@ +This is a snapshot of JavaScriptCore from + + git://gitorious.org/qtwebkit/qtwebkit.git + +The commit imported was from the + + jsc-for-qtscript-4.6-staging-24092009 branch/tag + +and has the sha1 checksum + + 6906f46c84e6b20612db58018334cb6823d0a18a diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri new file mode 100644 index 0000000..ded4701 --- /dev/null +++ b/src/3rdparty/javascriptcore/WebKit.pri @@ -0,0 +1,133 @@ +# Include file to make it easy to include WebKit into Qt projects + + +isEmpty(OUTPUT_DIR) { + CONFIG(debug, debug|release) { + OUTPUT_DIR=$$PWD/WebKitBuild/Debug + } else { # Release + OUTPUT_DIR=$$PWD/WebKitBuild/Release + } +} + +DEFINES += BUILDING_QT__=1 +building-libs { + win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 +} else { + CONFIG(QTDIR_build) { + QT += webkit + } else { + QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR + mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) { + LIBS += -framework QtWebKit + QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH + } else { + win32-*|wince* { + LIBS += -lQtWebKit$${QT_MAJOR_VERSION} + } else { + LIBS += -lQtWebKit + } + } + } + DEPENDPATH += $$PWD/WebKit/qt/Api +} + +DEFINES += USE_SYSTEM_MALLOC +CONFIG(release, debug|release) { + DEFINES += NDEBUG +} + +BASE_DIR = $$PWD +INCLUDEPATH += $$PWD/WebKit/qt/Api + +CONFIG -= warn_on +*-g++*:QMAKE_CXXFLAGS += -Wreturn-type -fno-strict-aliasing +#QMAKE_CXXFLAGS += -Wall -Wno-undef -Wno-unused-parameter + +# Enable GNU compiler extensions to the ARM compiler for all Qt ports using RVCT +symbian|*-armcc { + RVCT_COMMON_CFLAGS = --gnu --diag_suppress 68,111,177,368,830,1293 + RVCT_COMMON_CXXFLAGS = $$RVCT_COMMON_CFLAGS --no_parse_templates + DEFINES *= QT_NO_UITOOLS +} + +*-armcc { + QMAKE_CFLAGS += $$RVCT_COMMON_CFLAGS + QMAKE_CXXFLAGS += $$RVCT_COMMON_CXXFLAGS +} + +symbian { + QMAKE_CXXFLAGS.ARMCC += $$RVCT_COMMON_CXXFLAGS +} + +contains(DEFINES, QT_NO_UITOOLS): CONFIG -= uitools + +# Disable a few warnings on Windows. The warnings are also +# disabled in WebKitLibraries/win/tools/vsprops/common.vsprops +win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4503 -wd4800 -wd4819 -wd4996 + +# +# For builds inside Qt we interpret the output rule and the input of each extra compiler manually +# and add the resulting sources to the SOURCES variable, because the build inside Qt contains already +# all the generated files. We do not need to generate any extra compiler rules in that case. +# +# In addition this function adds a new target called 'generated_files' that allows manually calling +# all the extra compilers to generate all the necessary files for the build using 'make generated_files' +# +defineTest(addExtraCompiler) { + CONFIG(QTDIR_build) { + outputRule = $$eval($${1}.output) + outVariable = $$eval($${1}.variable_out) + !isEqual(outVariable,GENERATED_SOURCES):return(true) + + input = $$eval($${1}.input) + input = $$eval($$input) + + for(file,input) { + base = $$basename(file) + base ~= s/\..+// + newfile=$$replace(outputRule,\\$\\{QMAKE_FILE_BASE\\},$$base) + SOURCES += $$newfile + } + + export(SOURCES) + } else { + QMAKE_EXTRA_COMPILERS += $$1 + generated_files.depends += compiler_$${1}_make_all + export(QMAKE_EXTRA_COMPILERS) + export(generated_files.depends) + } + return(true) +} + +defineTest(addExtraCompilerWithHeader) { + addExtraCompiler($$1) + + eval(headerFile = $${2}) + isEmpty(headerFile) { + eval($${1}_header.output = $$eval($${1}.output)) + eval($${1}_header.output ~= s/\.cpp/.h/) + eval($${1}_header.output ~= s/\.c/.h/) + } else { + eval($${1}_header.output = $$headerFile) + } + + eval($${1}_header.input = $$eval($${1}.input)) + eval($${1}_header.commands = @echo -n '') + eval($${1}_header.depends = compiler_$${1}_make_all) + eval($${1}_header.variable_out = GENERATED_FILES) + + export($${1}_header.output) + export($${1}_header.input) + export($${1}_header.commands) + export($${1}_header.depends) + export($${1}_header.variable_out) + + !CONFIG(QTDIR_build): QMAKE_EXTRA_COMPILERS += $${1}_header + + export(QMAKE_EXTRA_COMPILERS) + export(generated_files.depends) + export(SOURCES) + + return(true) +} + diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog index 4a08347..9065b3a 100644 --- a/src/3rdparty/webkit/ChangeLog +++ b/src/3rdparty/webkit/ChangeLog @@ -1,3 +1,84 @@ +2009-09-23 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + Do not add unneeded include paths for gir files, and add the + include paths for headers manually instead of relying on our own + pc file and installed headers, since that adds a circular + dependency. + + * GNUmakefile.am: + +2009-09-23 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Xan Lopez. + + Minor reorganization to the patch landed in + http://trac.webkit.org/changeset/48670. Also move JSCore-1.0.gir + in the gtk directory as that's only useful to the Gtk port at the + moment. + + * GNUmakefile.am: + * configure.ac: + +2009-09-23 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + [GTK] We should generate our own gir file for introspection + https://bugs.webkit.org/show_bug.cgi?id=29603 + + Generate gir and typelib files for WebKit and JSCore. The JSCore + gir file is handwritten (since it's only useful, for now, as a + dependency of the WebKit gir file), the WebKit one is + autogenerated from the headers. + + * GNUmakefile.am: + * JSCore-1.0.gir: Added. + * configure.ac: + +2009-09-22 Philippe Normand <pnormand@igalia.com> + + Reviewed by Xan Lopez. + + link errors due to wrong UNICODE_LIBS on Ubuntu Jaunty + https://bugs.webkit.org/show_bug.cgi?id=29638 + + Call icu-cconfig with ldflags-libsonly to prevent having a -L + statement that could override libs installed in another prefix. + + * autotools/webkit.m4: + +2009-09-21 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + Bump version for 1.1.15 release. + + * configure.ac: + +2009-09-18 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha and Jan Alonzo. + + [GTK] context menu overriding API is very limited + https://bugs.webkit.org/show_bug.cgi?id=27546 + + Add new tests to the build. + + * GNUmakefile.am: + +2009-09-18 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha and Jan Alonzo. + + [GTK] context menu overriding API is very limited + https://bugs.webkit.org/show_bug.cgi?id=27546 + + Add WebKitHitTestResult to the build. + + * GNUmakefile.am: + 2009-09-10 Laszlo Gombos <laszlo.1.gombos@nokia.com> Reviewed by Ariya Hidayat. diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSStringRef.h b/src/3rdparty/webkit/JavaScriptCore/API/JSStringRef.h index 8b17ee2..c58b958 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSStringRef.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSStringRef.h @@ -37,7 +37,7 @@ extern "C" { #endif -#if !defined(WIN32) && !defined(_WIN32) +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__) /*! @typedef JSChar @abstract A Unicode character. diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 8aa8c1d..4899919 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,532 @@ +2009-09-23 Geoffrey Garen <ggaren@apple.com> + + A piece of my last patch that I forgot. + + * wtf/HashCountedSet.h: + (WTF::::clear): Added HashCountedSet::clear. + +2009-09-24 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Avoid __clear_cache built-in function if DISABLE_BUILTIN_CLEAR_CACHE define is set + https://bugs.webkit.org/show_bug.cgi?id=28886 + + There are some GCC packages (for example GCC-2006q3 from CodeSourcery) + which contain __clear_cache built-in function only for C while the C++ + version of __clear_cache is missing on ARM architectures. + + Fixed a small bug in the inline assembly of cacheFlush function on + ARM_TRADITIONAL. + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-09-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added the ability to swap vectors with inline capacities, so you can + store a vector with inline capacity in a hash table. + + * wtf/Vector.h: + (WTF::swap): + (WTF::VectorBuffer::swap): + +2009-09-23 David Kilzer <ddkilzer@apple.com> + + Move definition of USE(PLUGIN_HOST_PROCESS) from WebKitPrefix.h to Platform.h + + Reviewed by Mark Rowe. + + * wtf/Platform.h: Define WTF_USE_PLUGIN_HOST_PROCESS to 1 when + building on 64-bit SnowLeopard. Define to 0 elsewhere. + +2009-09-22 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Code sampling builds are broken. + https://bugs.webkit.org/show_bug.cgi?id=29662 + + Fix build. + + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * bytecode/SamplingTool.cpp: + (JSC::ScriptSampleRecord::sample): + (JSC::SamplingTool::doRun): + (JSC::SamplingTool::notifyOfScope): + (JSC::compareScriptSampleRecords): + (JSC::SamplingTool::dump): + * bytecode/SamplingTool.h: + (JSC::ScriptSampleRecord::ScriptSampleRecord): + (JSC::ScriptSampleRecord::~ScriptSampleRecord): + (JSC::SamplingTool::SamplingTool): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::emitNewFunction): + (JSC::BytecodeGenerator::emitNewFunctionExpression): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::makeFunction): + * debugger/Debugger.cpp: + (JSC::evaluateInGlobalCallFrame): + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::evaluate): + * parser/Nodes.cpp: + (JSC::ScopeNode::ScopeNode): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::fromGlobalCode): + * runtime/Executable.h: + (JSC::ScriptExecutable::ScriptExecutable): + (JSC::EvalExecutable::EvalExecutable): + (JSC::EvalExecutable::create): + (JSC::ProgramExecutable::ProgramExecutable): + (JSC::FunctionExecutable::create): + (JSC::FunctionExecutable::FunctionExecutable): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + +2009-09-22 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + * wtf/Forward.h: Added PassOwnPtr. + +2009-09-22 Yaar Schnitman <yaar@chromium.org> + + Reviewed by David Levin. + + Ported chromium.org's javascriptcore.gyp for the webkit chromium port. + + https://bugs.webkit.org/show_bug.cgi?id=29617 + + * JavaScriptCore.gyp/JavaScriptCore.gyp: Added. + +2009-09-22 Thiago Macieira <thiago.macieira@nokia.com> + + Reviewed by Simon Hausmann. + + Fix compilation with WINSCW: no varargs macros + + Disable variadic arguments for WINSCW just like we do + for MSVC7. + + * wtf/Assertions.h: + +2009-09-22 Kent Hansen <khansen@trolltech.com> + + Reviewed by Simon Hausmann. + + Disable variadic macros on MSVC7. + + This was originally added in r26589 but not extended + when LOG_DISABLED/ASSERT_DISABLED was introduced. + + * wtf/Assertions.h: + +2009-09-22 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed build fix for Windows CE < 5 + + Define WINCEBASIC to disable the IsDebuggerPresent() code in + wtf/Assertions.cpp. + + * JavaScriptCore.pri: + +2009-09-22 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by Simon Hausmann. + + Fix major memory leak in JavaScriptCore RegisterFile on Windows CE + + https://bugs.webkit.org/show_bug.cgi?id=29367 + + On Widows CE we must decommit all committed pages before we release + them. See VirtualFree documentation. + Desktop Windows behaves much smoother in this situation. + + * interpreter/RegisterFile.cpp: + (JSC::RegisterFile::~RegisterFile): + +2009-09-21 Greg Bolsinga <bolsinga@apple.com> + + Reviewed by Simon Fraser & Sam Weinig. + + Add ENABLE(ORIENTATION_EVENTS) + https://bugs.webkit.org/show_bug.cgi?id=29508 + + * wtf/Platform.h: Also sort PLATFORM(IPHONE) #defines. + +2009-09-21 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Eric Seidel. + + [Fix] SourceCode's uninitialized member + + Potential source of crashes and bugs was fixed. Default constructor + didn't initialized m_provider member. + + https://bugs.webkit.org/show_bug.cgi?id=29364 + + * parser/SourceCode.h: + (JSC::SourceCode::SourceCode): + +2009-09-21 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + REGRESSION (r48582): Crash in StructureStubInfo::initPutByIdTransition when reloading trac.webkit.org + https://bugs.webkit.org/show_bug.cgi?id=29599 + + It is unsafe to attempt to cache new property transitions on + dictionaries of any type. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCachePutByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + +2009-09-21 Oliver Hunt <oliver@apple.com> + + RS=Maciej Stachowiak. + + Re-land SNES fix with corrected assertion. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * runtime/BatchedTransitionOptimizer.h: + (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer): + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::getEnumerablePropertyNames): + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::removePropertyTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::toCacheableDictionaryTransition): + (JSC::Structure::toUncacheableDictionaryTransition): + (JSC::Structure::fromDictionaryTransition): + (JSC::Structure::removePropertyWithoutTransition): + * runtime/Structure.h: + (JSC::Structure::isDictionary): + (JSC::Structure::isUncacheableDictionary): + (JSC::Structure::): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-09-21 Adam Roben <aroben@apple.com> + + Revert r48573, as it caused many assertion failures + + * interpreter/Interpreter.cpp: + * jit/JITStubs.cpp: + * runtime/BatchedTransitionOptimizer.h: + * runtime/JSObject.cpp: + * runtime/Structure.cpp: + * runtime/Structure.h: + * runtime/StructureChain.cpp: + +2009-09-21 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed make dist build fix. Missing files. + + * GNUmakefile.am: + +2009-09-19 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam 'Cabin Boy' Weinig. + + Fix stack alignment with ARM THUMB2 JIT. + https://bugs.webkit.org/show_bug.cgi?id=29526 + + Stack is currently being decremented by 0x3c, bump this to 0x40 to make this a + multiple of 16 bytes. + + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + * jit/JITStubs.h: + +2009-09-20 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + SNES is too slow + https://bugs.webkit.org/show_bug.cgi?id=29534 + + The problem was that the emulator used multiple classes with + more properties than our dictionary cutoff allowed, this resulted + in more or less all critical logic inside the emulator requiring + uncached property access. + + Rather than simply bumping the dictionary cutoff, this patch + recognises that there are two ways to create a "dictionary" + structure. Either by adding a large number of properties, or + by removing a property. In the case of adding properties we + know all the existing properties will maintain their existing + offsets, so we could cache access to those properties, if we + know they won't be removed. + + To make this possible, this patch adds the logic required to + distinguish a dictionary created by addition from one created + by removal. With this logic in place we can now cache access + to objects with large numbers of properties. + + SNES performance improved by more than 6x. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * runtime/BatchedTransitionOptimizer.h: + (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer): + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::getEnumerablePropertyNames): + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::removePropertyTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::toCacheableDictionaryTransition): + (JSC::Structure::toUncacheableDictionaryTransition): + (JSC::Structure::fromDictionaryTransition): + (JSC::Structure::removePropertyWithoutTransition): + * runtime/Structure.h: + (JSC::Structure::isDictionary): + (JSC::Structure::isUncacheableDictionary): + (JSC::Structure::): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Implement ES5 Object.create function + https://bugs.webkit.org/show_bug.cgi?id=29524 + + Implement Object.create. Very simple patch, effectively Object.defineProperties + only creating the target object itself. + + * runtime/CommonIdentifiers.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorCreate): + +2009-09-19 Dan Bernstein <mitz@apple.com> + + Fix clean debug builds. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-19 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by George Staikos. + + QtWebKit Windows CE compile fix + + https://bugs.webkit.org/show_bug.cgi?id=29379 + + There is no _aligned_alloc or _aligned_free on Windows CE. + We just use the Windows code that was there before and use VirtualAlloc. + But that also means that the BLOCK_SIZE must be 64K as this function + allocates on 64K boundaries. + + * runtime/Collector.cpp: + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlock): + * runtime/Collector.h: + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by Sam Weinig. + + Implement ES5 Object.defineProperties function + https://bugs.webkit.org/show_bug.cgi?id=29522 + + Implement Object.defineProperties. Fairly simple patch, simply makes use of + existing functionality used for defineProperty. + + * runtime/CommonIdentifiers.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::defineProperties): + (JSC::objectConstructorDefineProperties): + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Build fix). + + Windows build fix part2 + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-19 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (Buildfix). + + Windows build fix part 1. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-09-18 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Implement ES5 Object.defineProperty function + https://bugs.webkit.org/show_bug.cgi?id=29503 + + Implement Object.defineProperty. This requires adding the API to + ObjectConstructor, along with a helper function that implements the + ES5 internal [[ToPropertyDescriptor]] function. It then adds + JSObject::defineOwnProperty that implements the appropriate ES5 semantics. + Currently defineOwnProperty uses a delete followed by a put to redefine + attributes of a property, clearly this is less efficient than it could be + but we can improve this if it needs to be possible in future. + + * JavaScriptCore.exp: + * debugger/DebuggerActivation.cpp: + (JSC::DebuggerActivation::defineGetter): + (JSC::DebuggerActivation::defineSetter): + * debugger/DebuggerActivation.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + Update defineGetter/Setter calls + * runtime/CommonIdentifiers.h: + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::defineGetter): + (JSC::JSGlobalObject::defineSetter): + * runtime/JSGlobalObject.h: + * runtime/JSObject.cpp: + (JSC::JSObject::defineGetter): + (JSC::JSObject::defineSetter): + (JSC::putDescriptor): + (JSC::JSObject::defineOwnProperty): + * runtime/JSObject.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorGetOwnPropertyDescriptor): + (JSC::toPropertyDescriptor): + (JSC::objectConstructorDefineProperty): + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncDefineGetter): + (JSC::objectProtoFuncDefineSetter): + * runtime/PropertyDescriptor.cpp: + (JSC::PropertyDescriptor::writable): + (JSC::PropertyDescriptor::enumerable): + (JSC::PropertyDescriptor::configurable): + (JSC::PropertyDescriptor::isDataDescriptor): + (JSC::PropertyDescriptor::isGenericDescriptor): + (JSC::PropertyDescriptor::isAccessorDescriptor): + (JSC::PropertyDescriptor::getter): + (JSC::PropertyDescriptor::setter): + (JSC::PropertyDescriptor::setDescriptor): + (JSC::PropertyDescriptor::setAccessorDescriptor): + (JSC::PropertyDescriptor::setWritable): + (JSC::PropertyDescriptor::setEnumerable): + (JSC::PropertyDescriptor::setConfigurable): + (JSC::PropertyDescriptor::setSetter): + (JSC::PropertyDescriptor::setGetter): + (JSC::PropertyDescriptor::equalTo): + (JSC::PropertyDescriptor::attributesEqual): + (JSC::PropertyDescriptor::attributesWithOverride): + * runtime/PropertyDescriptor.h: + (JSC::PropertyDescriptor::PropertyDescriptor): + (JSC::PropertyDescriptor::value): + (JSC::PropertyDescriptor::setValue): + (JSC::PropertyDescriptor::isEmpty): + (JSC::PropertyDescriptor::writablePresent): + (JSC::PropertyDescriptor::enumerablePresent): + (JSC::PropertyDescriptor::configurablePresent): + (JSC::PropertyDescriptor::setterPresent): + (JSC::PropertyDescriptor::getterPresent): + (JSC::PropertyDescriptor::operator==): + (JSC::PropertyDescriptor::): + +2009-09-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Build fix to enable ARM_THUMB2 on Linux + https://bugs.webkit.org/show_bug.cgi?id= + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + * jit/JITStubs.cpp: + * wtf/Platform.h: + +2009-09-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + 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. + + * assembler/ARMAssembler.cpp: + * assembler/ARMAssembler.h: + * assembler/ARMv7Assembler.h: + * assembler/MacroAssembler.h: + * assembler/MacroAssemblerARM.cpp: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerCodeRef.h: + (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr): + * jit/ExecutableAllocator.h: + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::beginUninterruptedSequence): + (JSC::JIT::preserveReturnAddressAfterCall): + (JSC::JIT::restoreReturnAddressBeforeReturn): + (JSC::JIT::restoreArgumentReference): + (JSC::JIT::restoreArgumentReferenceForTrampoline): + * jit/JITOpcodes.cpp: + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + * jit/JITStubs.h: + * wtf/Platform.h: + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): + +2009-09-18 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by Simon Hausmann. + + Fix the Qt/Windows CE build. + + * JavaScriptCore.pri: Build the ce_time.cpp functions from + within Qt externally. + * wtf/DateMath.cpp: Removed unnecessary Qt #ifdef, for the + Qt build these functions are no external, too. + 2009-09-17 Janne Koskinen <janne.p.koskinen@digia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri index bd80add..7a815e3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri @@ -50,10 +50,9 @@ win32-* { } } -win32-msvc*: INCLUDEPATH += $$PWD/os-win32 wince* { - INCLUDEPATH += $$PWD/os-win32 SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.cpp + DEFINES += WINCEBASIC } include(pcre/pcre.pri) diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro new file mode 100644 index 0000000..0cd2e1a --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro @@ -0,0 +1,69 @@ +# JavaScriptCore - qmake build info +CONFIG += building-libs +include($$PWD/../WebKit.pri) + +TEMPLATE = lib +CONFIG += staticlib +TARGET = JavaScriptCore + +CONFIG += depend_includepath + +contains(QT_CONFIG, embedded):CONFIG += embedded + +CONFIG(QTDIR_build) { + GENERATED_SOURCES_DIR = $$PWD/generated + OLDDESTDIR = $$DESTDIR + include($$QT_SOURCE_TREE/src/qbase.pri) + INSTALLS = + DESTDIR = $$OLDDESTDIR + PRECOMPILED_HEADER = $$PWD/../WebKit/qt/WebKit_pch.h + DEFINES *= NDEBUG +} + +isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp +GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP} + +INCLUDEPATH += $$GENERATED_SOURCES_DIR + +!CONFIG(QTDIR_build) { + CONFIG(debug, debug|release) { + OBJECTS_DIR = obj/debug + } else { # Release + OBJECTS_DIR = obj/release + } +} + +CONFIG(release):!CONFIG(QTDIR_build) { + contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols + unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions +} + +linux-*: DEFINES += HAVE_STDINT_H +freebsd-*: DEFINES += HAVE_PTHREAD_NP_H + +DEFINES += BUILD_WEBKIT + +win32-*: DEFINES += _HAS_TR1=0 + +# Pick up 3rdparty libraries from INCLUDE/LIB just like with MSVC +win32-g++ { + TMPPATH = $$quote($$(INCLUDE)) + QMAKE_INCDIR_POST += $$split(TMPPATH,";") + TMPPATH = $$quote($$(LIB)) + QMAKE_LIBDIR_POST += $$split(TMPPATH,";") +} + +DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 + +DEFINES += WTF_CHANGES=1 + +include(JavaScriptCore.pri) + +QMAKE_EXTRA_TARGETS += generated_files + +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/assembler/ARMAssembler.cpp b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.cpp index 77d7a53..1324586 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "ARMAssembler.h" @@ -390,4 +390,4 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator) } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.h b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.h index 0b04bb4..9f9a450 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMAssembler.h @@ -29,7 +29,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "AssemblerBufferWithConstantPool.h" #include <wtf/Assertions.h> @@ -764,6 +764,6 @@ namespace JSC { } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #endif // ARMAssembler_h diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h index e920255..078de44 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/ARMv7Assembler.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) #include "AssemblerBuffer.h" #include <wtf/Assertions.h> @@ -1753,6 +1753,6 @@ private: } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) #endif // ARMAssembler_h diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssembler.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssembler.h index 9e1c5d3..2743ab4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssembler.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssembler.h @@ -30,11 +30,11 @@ #if ENABLE(ASSEMBLER) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) #include "MacroAssemblerARMv7.h" namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }; -#elif PLATFORM(ARM) +#elif PLATFORM(ARM_TRADITIONAL) #include "MacroAssemblerARM.h" namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.cpp index 33fac64..43648c4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "MacroAssemblerARM.h" @@ -64,4 +64,4 @@ const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent(); } -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h index 4a7c10a..0c696c9 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -30,7 +30,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #include "ARMAssembler.h" #include "AbstractMacroAssembler.h" @@ -797,6 +797,6 @@ private: } -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) #endif // MacroAssemblerARM_h diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 341a7ff..568260a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -37,7 +37,7 @@ // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid // instruction address on the platform (for example, check any alignment requirements). -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded // into the processor are decorated with the bottom bit set, indicating that this is // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both @@ -124,7 +124,7 @@ public: } explicit MacroAssemblerCodePtr(void* value) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // Decorate the pointer as a thumb code pointer. : m_value(reinterpret_cast<char*>(value) + 1) #else @@ -141,7 +141,7 @@ public: } void* executableAddress() const { return m_value; } -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // To use this pointer as a data address remove the decoration. void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; } #else diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h index 0e1fb1e..05834fc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h @@ -50,7 +50,7 @@ namespace JSC { evalExecutable = m_cacheMap.get(evalSource.rep()); if (!evalExecutable) { - evalExecutable = EvalExecutable::create(makeSource(evalSource)); + evalExecutable = EvalExecutable::create(exec, makeSource(evalSource)); exceptionValue = evalExecutable->compile(exec, scopeChain); if (exceptionValue) return 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp index 8d0faa1..865c919 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp @@ -157,7 +157,7 @@ void SamplingThread::stop() } -void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) +void ScriptSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) { if (!m_samples) { m_size = codeBlock->instructions().size(); @@ -196,8 +196,8 @@ void SamplingTool::doRun() #if ENABLE(CODEBLOCK_SAMPLING) if (CodeBlock* codeBlock = sample.codeBlock()) { - MutexLocker locker(m_scopeSampleMapMutex); - ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); + MutexLocker locker(m_scriptSampleMapMutex); + ScriptSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); ASSERT(record); record->sample(codeBlock, sample.vPC()); } @@ -209,13 +209,13 @@ void SamplingTool::sample() s_samplingTool->doRun(); } -void SamplingTool::notifyOfScope(ScopeNode* scope) +void SamplingTool::notifyOfScope(ScriptExecutable* script) { #if ENABLE(CODEBLOCK_SAMPLING) - MutexLocker locker(m_scopeSampleMapMutex); - m_scopeSampleMap->set(scope, new ScopeSampleRecord(scope)); + MutexLocker locker(m_scriptSampleMapMutex); + m_scopeSampleMap->set(script, new ScriptSampleRecord(script)); #else - UNUSED_PARAM(scope); + UNUSED_PARAM(script); #endif } @@ -254,10 +254,10 @@ static int compareLineCountInfoSampling(const void* left, const void* right) return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0; } -static int compareScopeSampleRecords(const void* left, const void* right) +static int compareScriptSampleRecords(const void* left, const void* right) { - const ScopeSampleRecord* const leftValue = *static_cast<const ScopeSampleRecord* const *>(left); - const ScopeSampleRecord* const rightValue = *static_cast<const ScopeSampleRecord* const *>(right); + const ScriptSampleRecord* const leftValue = *static_cast<const ScriptSampleRecord* const *>(left); + const ScriptSampleRecord* const rightValue = *static_cast<const ScriptSampleRecord* const *>(right); return (leftValue->m_sampleCount < rightValue->m_sampleCount) ? 1 : (leftValue->m_sampleCount > rightValue->m_sampleCount) ? -1 : 0; } @@ -318,26 +318,26 @@ void SamplingTool::dump(ExecState* exec) // (3) Build and sort 'codeBlockSamples' array. int scopeCount = m_scopeSampleMap->size(); - Vector<ScopeSampleRecord*> codeBlockSamples(scopeCount); - ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); + Vector<ScriptSampleRecord*> codeBlockSamples(scopeCount); + ScriptSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); for (int i = 0; i < scopeCount; ++i, ++iter) codeBlockSamples[i] = iter->second; - qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); + qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScriptSampleRecord*), compareScriptSampleRecords); // (4) Print data from 'codeBlockSamples' array. printf("\nCodeBlock samples\n\n"); for (int i = 0; i < scopeCount; ++i) { - ScopeSampleRecord* record = codeBlockSamples[i]; + ScriptSampleRecord* record = codeBlockSamples[i]; CodeBlock* codeBlock = record->m_codeBlock; double blockPercent = (record->m_sampleCount * 100.0) / m_sampleCount; if (blockPercent >= 1) { //Instruction* code = codeBlock->instructions().begin(); - printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); + printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); if (i < 10) { HashMap<unsigned,unsigned> lineCounts; codeBlock->dump(exec); diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h index 1a3f7cf..711b086 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h @@ -38,6 +38,8 @@ namespace JSC { + class ScriptExecutable; + class SamplingFlags { friend class JIT; public: @@ -92,9 +94,9 @@ namespace JSC { class ScopeNode; struct Instruction; - struct ScopeSampleRecord { - ScopeSampleRecord(ScopeNode* scope) - : m_scope(scope) + struct ScriptSampleRecord { + ScriptSampleRecord(ScriptExecutable* executable) + : m_executable(executable) , m_codeBlock(0) , m_sampleCount(0) , m_opcodeSampleCount(0) @@ -103,7 +105,7 @@ namespace JSC { { } - ~ScopeSampleRecord() + ~ScriptSampleRecord() { if (m_samples) free(m_samples); @@ -111,7 +113,7 @@ namespace JSC { void sample(CodeBlock*, Instruction*); - RefPtr<ScopeNode> m_scope; + ScriptExecutable* m_executable; CodeBlock* m_codeBlock; int m_sampleCount; int m_opcodeSampleCount; @@ -119,7 +121,7 @@ namespace JSC { unsigned m_size; }; - typedef WTF::HashMap<ScopeNode*, ScopeSampleRecord*> ScopeSampleRecordMap; + typedef WTF::HashMap<ScriptExecutable*, ScriptSampleRecord*> ScriptSampleRecordMap; class SamplingThread { public: @@ -193,7 +195,7 @@ namespace JSC { , m_sampleCount(0) , m_opcodeSampleCount(0) #if ENABLE(CODEBLOCK_SAMPLING) - , m_scopeSampleMap(new ScopeSampleRecordMap()) + , m_scopeSampleMap(new ScriptSampleRecordMap()) #endif { memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples)); @@ -210,7 +212,7 @@ namespace JSC { void setup(); void dump(ExecState*); - void notifyOfScope(ScopeNode* scope); + void notifyOfScope(ScriptExecutable* scope); void sample(CodeBlock* codeBlock, Instruction* vPC) { @@ -266,8 +268,8 @@ namespace JSC { unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs]; #if ENABLE(CODEBLOCK_SAMPLING) - Mutex m_scopeSampleMapMutex; - OwnPtr<ScopeSampleRecordMap> m_scopeSampleMap; + Mutex m_scriptSampleMapMutex; + OwnPtr<ScriptSampleRecordMap> m_scopeSampleMap; #endif }; diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index af8f784..8951ce3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -273,7 +273,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d } else { for (size_t i = 0; i < functionStack.size(); ++i) { FunctionBodyNode* function = functionStack[i]; - globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(function), scopeChain.node()), DontDelete); + globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain.node()), DontDelete); } for (size_t i = 0; i < varStack.size(); ++i) { if (globalObject->hasProperty(exec, *varStack[i].first)) @@ -399,7 +399,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); for (size_t i = 0; i < functionStack.size(); ++i) - m_codeBlock->addFunctionDecl(makeFunction(functionStack[i])); + m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i])); const DeclarationStacks::VarStack& varStack = evalNode->varStack(); unsigned numVariables = varStack.size(); @@ -1316,7 +1316,7 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function) { - unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function)); + unsigned index = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)); emitOpcode(op_new_func); instructions().append(dst->index()); @@ -1336,7 +1336,7 @@ RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp) RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n) { FunctionBodyNode* function = n->body(); - unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function)); + unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function)); emitOpcode(op_new_func_exp); instructions().append(r0->index()); diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 650b362..1a83ce9 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -417,9 +417,14 @@ namespace JSC { RegisterID* addConstantValue(JSValue); unsigned addRegExp(RegExp*); - PassRefPtr<FunctionExecutable> makeFunction(FunctionBodyNode* body) + PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body) { - return FunctionExecutable::create(body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + } + + PassRefPtr<FunctionExecutable> makeFunction(JSGlobalData* globalData, FunctionBodyNode* body) + { + return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); } Vector<Instruction>& instructions() { return m_codeBlock->instructions(); } diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/Debugger.cpp b/src/3rdparty/webkit/JavaScriptCore/debugger/Debugger.cpp index 61167d4..db02329 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/Debugger.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/Debugger.cpp @@ -100,7 +100,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG { CallFrame* globalCallFrame = globalObject->globalExec(); - EvalExecutable eval(makeSource(script)); + EvalExecutable eval(globalCallFrame, makeSource(script)); JSObject* error = eval.compile(globalCallFrame, globalCallFrame->scopeChain()); if (error) return error; diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.cpp b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.cpp index 7a68d7d..5cc9a9f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.cpp @@ -81,14 +81,14 @@ bool DebuggerActivation::getPropertyAttributes(JSC::ExecState* exec, const Ident return m_activation->getPropertyAttributes(exec, propertyName, attributes); } -void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { - m_activation->defineGetter(exec, propertyName, getterFunction); + m_activation->defineGetter(exec, propertyName, getterFunction, attributes); } -void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { - m_activation->defineSetter(exec, propertyName, setterFunction); + m_activation->defineSetter(exec, propertyName, setterFunction, attributes); } JSValue DebuggerActivation::lookupGetter(ExecState* exec, const Identifier& propertyName) diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h index 06aea5a..dd34265 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h @@ -44,8 +44,8 @@ namespace JSC { virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes); virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerCallFrame.cpp index 9c8ca2a..88b14e6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerCallFrame.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerCallFrame.cpp @@ -79,7 +79,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c if (!m_callFrame->codeBlock()) return JSValue(); - EvalExecutable eval(makeSource(script)); + EvalExecutable eval(m_callFrame, makeSource(script)); JSObject* error = eval.compile(m_callFrame, m_callFrame->scopeChain()); if (error) return error; diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp index 4560db0..8a8fb3c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp @@ -169,7 +169,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* PropertySlot slot(globalObject); if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); - if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) { + if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { if (vPC[4].u.structure) vPC[4].u.structure->deref(); globalObject->structure()->ref(); @@ -953,7 +953,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { vPC[0] = getOpcode(op_put_by_id_generic); return; } @@ -988,6 +988,10 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { + if (structure->isDictionary()) { + vPC[0] = getOpcode(op_put_by_id_generic); + return; + } vPC[0] = getOpcode(op_put_by_id_transition); vPC[4] = structure->previousID(); vPC[5] = structure; @@ -1040,7 +1044,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* Structure* structure = asCell(baseValue)->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { vPC[0] = getOpcode(op_get_by_id_generic); return; } @@ -3731,7 +3735,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSObject* baseObj = asObject(callFrame->r(base).jsValue()); Identifier& ident = callFrame->codeBlock()->identifier(property); ASSERT(callFrame->r(function).jsValue().isObject()); - baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); + baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); ++vPC; NEXT_INSTRUCTION(); diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/RegisterFile.cpp b/src/3rdparty/webkit/JavaScriptCore/interpreter/RegisterFile.cpp index 06ddefc..5424199 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/RegisterFile.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/RegisterFile.cpp @@ -36,6 +36,9 @@ RegisterFile::~RegisterFile() #if HAVE(MMAP) munmap(m_buffer, ((m_max - m_start) + m_maxGlobals) * sizeof(Register)); #elif HAVE(VIRTUALALLOC) +#if PLATFORM(WINCE) + VirtualFree(m_buffer, DWORD(m_commitEnd) - DWORD(m_buffer), MEM_DECOMMIT); +#endif VirtualFree(m_buffer, 0, MEM_RELEASE); #else fastFree(m_buffer); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 51ada03..12e2a32 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -180,7 +180,7 @@ public: static void cacheFlush(void*, size_t) { } -#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) +#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) static void cacheFlush(void* code, size_t size) { sys_dcache_flush(code, size); @@ -191,24 +191,29 @@ public: { User::IMB_Range(code, static_cast<char*>(code) + size); } -#elif PLATFORM(ARM) +#elif PLATFORM(ARM) && COMPILER(GCC) && (GCC_VERSION >= 30406) && !defined(DISABLE_BUILTIN_CLEAR_CACHE) static void cacheFlush(void* code, size_t size) { - #if COMPILER(GCC) && (GCC_VERSION >= 30406) __clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(code) + size); - #else - const int syscall = 0xf0002; - __asm __volatile ( - "mov r0, %0\n" - "mov r1, %1\n" - "mov r7, %2\n" - "mov r2, #0x0\n" - "swi 0x00000000\n" - : - : "r" (code), "r" (reinterpret_cast<char*>(code) + size), "r" (syscall) - : "r0", "r1", "r7"); - #endif // COMPILER(GCC) && (GCC_VERSION >= 30406) } +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) + static void cacheFlush(void* code, size_t size) + { + asm volatile ( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "mov r7, #0xf0000\n" + "add r7, r7, #0x2\n" + "mov r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (code), "r" (reinterpret_cast<char*>(code) + size) + : "r0", "r1"); + } +#else + #error "The cacheFlush support is missing on this platform." #endif private: diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h index f7ac20e..5c58e9d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h @@ -226,7 +226,7 @@ namespace JSC { static const FPRegisterID fpRegT0 = X86Registers::xmm0; static const FPRegisterID fpRegT1 = X86Registers::xmm1; static const FPRegisterID fpRegT2 = X86Registers::xmm2; -#elif PLATFORM_ARM_ARCH(7) +#elif PLATFORM(ARM_THUMB2) static const RegisterID returnValueRegister = ARMRegisters::r0; static const RegisterID cachedResultRegister = ARMRegisters::r0; static const RegisterID firstArgumentRegister = ARMRegisters::r0; @@ -242,7 +242,7 @@ namespace JSC { static const FPRegisterID fpRegT0 = ARMRegisters::d0; static const FPRegisterID fpRegT1 = ARMRegisters::d1; static const FPRegisterID fpRegT2 = ARMRegisters::d2; -#elif PLATFORM(ARM) +#elif PLATFORM(ARM_TRADITIONAL) static const RegisterID returnValueRegister = ARMRegisters::r0; static const RegisterID cachedResultRegister = ARMRegisters::r0; static const RegisterID firstArgumentRegister = ARMRegisters::r0; @@ -571,7 +571,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 11; static const int patchOffsetMethodCheckProtoStruct = 18; static const int patchOffsetMethodCheckPutFunction = 29; -#elif PLATFORM_ARM_ARCH(7) +#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; @@ -594,7 +594,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 18; static const int patchOffsetMethodCheckProtoStruct = 28; static const int patchOffsetMethodCheckPutFunction = 46; -#elif PLATFORM(ARM) +#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; static const int patchOffsetPutByIdExternalLoad = 16; @@ -620,7 +620,7 @@ namespace JSC { #endif #endif // USE(JSVALUE32_64) -#if PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_TRADITIONAL) // sequenceOpCall static const int sequenceOpCallInstructionSpace = 12; static const int sequenceOpCallConstantSpace = 2; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h index 60c9658..e69e273 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h @@ -110,7 +110,7 @@ ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function) ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace) { -#if PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_TRADITIONAL) #ifndef NDEBUG // Ensure the label after the sequence can also fit insnSpace += sizeof(ARMWord); @@ -139,38 +139,38 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) #endif -#if PLATFORM(X86) || PLATFORM(X86_64) || (PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7)) +#if PLATFORM(ARM_THUMB2) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { - pop(reg); + move(linkRegister, reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg) { - push(reg); + move(reg, linkRegister); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) { - push(address); + loadPtr(address, linkRegister); } -#elif PLATFORM_ARM_ARCH(7) +#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { - move(linkRegister, reg); + pop(reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg) { - move(reg, linkRegister); + push(reg); } ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) { - loadPtr(address, linkRegister); + push(address); } #endif @@ -186,7 +186,7 @@ ALWAYS_INLINE void JIT::restoreArgumentReference() { move(stackPointerRegister, firstArgumentRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); -#if PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_TRADITIONAL) move(ctiReturnRegister, ARMRegisters::lr); #endif } @@ -195,7 +195,7 @@ 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_ARCH(7) +#elif PLATFORM(ARM_THUMB2) 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 1c9cd7e..28d630b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp @@ -1681,7 +1681,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // so pull them off now addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); -#elif PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) +#elif PLATFORM(ARM_TRADITIONAL) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); // Allocate stack space for our arglist diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp index 4ab58d5..055a536 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp @@ -69,6 +69,12 @@ namespace JSC { #define SYMBOL_STRING(name) #name #endif +#if PLATFORM(IPHONE) +#define THUMB_FUNC_PARAM(name) SYMBOL_STRING(name) +#else +#define THUMB_FUNC_PARAM(name) +#endif + #if USE(JSVALUE32_64) #if COMPILER(GCC) && PLATFORM(X86) @@ -193,7 +199,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM_ARM_ARCH(7) +#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." @@ -204,7 +210,7 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "sub sp, sp, #0x3c" "\n" "str lr, [sp, #0x20]" "\n" @@ -230,7 +236,7 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" "bl " SYMBOL_STRING(cti_vm_throw) "\n" @@ -247,7 +253,7 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" @@ -452,7 +458,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM_ARM_ARCH(7) +#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." @@ -463,9 +469,9 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" - "sub sp, sp, #0x3c" "\n" + "sub sp, sp, #0x40" "\n" "str lr, [sp, #0x20]" "\n" "str r4, [sp, #0x24]" "\n" "str r5, [sp, #0x28]" "\n" @@ -480,7 +486,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" "ldr lr, [sp, #0x20]" "\n" - "add sp, sp, #0x3c" "\n" + "add sp, sp, #0x40" "\n" "bx lr" "\n" ); @@ -489,7 +495,7 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" "bl " SYMBOL_STRING(cti_vm_throw) "\n" @@ -497,7 +503,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" "ldr lr, [sp, #0x20]" "\n" - "add sp, sp, #0x3c" "\n" + "add sp, sp, #0x40" "\n" "bx lr" "\n" ); @@ -506,7 +512,7 @@ asm volatile ( ".align 2" "\n" ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" ".thumb" "\n" -".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" @@ -516,7 +522,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "bx lr" "\n" ); -#elif COMPILER(GCC) && PLATFORM(ARM) +#elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL) asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" @@ -636,7 +642,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) { JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types), // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT // macros. @@ -649,7 +655,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == 0x34); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == 0x38); // The fifth argument is the first item already on the stack. - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x3c); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x40); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 0x1C); #endif @@ -673,7 +679,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } @@ -689,7 +695,7 @@ 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()) { + if (!prototypeChain->isCacheable() || structure->isDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } @@ -737,7 +743,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co JSCell* baseCell = asCell(baseValue); Structure* structure = baseCell->structure(); - if (structure->isDictionary()) { + if (structure->isUncacheableDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -876,7 +882,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD } \ } while (0) -#if PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_THUMB2) #define DEFINE_STUB_FUNCTION(rtype, op) \ extern "C" { \ @@ -887,7 +893,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ".align 2" "\n" \ ".globl " SYMBOL_STRING(cti_##op) "\n" \ ".thumb" "\n" \ - ".thumb_func " SYMBOL_STRING(cti_##op) "\n" \ + ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \ SYMBOL_STRING(cti_##op) ":" "\n" \ "str lr, [sp, #0x1c]" "\n" \ "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ @@ -1148,7 +1154,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) JSObject* slotBaseObject; if (baseValue.isCell() && slot.isCacheable() - && !(structure = asCell(baseValue)->structure())->isDictionary() + && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary() && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific) && specific ) { @@ -1222,7 +1228,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (baseValue.isCell() && slot.isCacheable() - && !asCell(baseValue)->structure()->isDictionary() + && !asCell(baseValue)->structure()->isUncacheableDictionary() && slot.slotBase() == baseValue) { CodeBlock* codeBlock = callFrame->codeBlock(); @@ -1293,7 +1299,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) CHECK_FOR_EXCEPTION(); - if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) { + if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) { ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); return JSValue::encode(result); } @@ -2182,7 +2188,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global) PropertySlot slot(globalObject); if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); - if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) { + if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex); if (globalResolveInfo.structure) globalResolveInfo.structure->deref(); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h index 1dbdeaa..46973ee 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h @@ -129,7 +129,7 @@ namespace JSC { #if COMPILER(MSVC) #pragma pack(pop) #endif // COMPILER(MSVC) -#elif PLATFORM_ARM_ARCH(7) +#elif PLATFORM(ARM_THUMB2) struct JITStackFrame { void* reserved; // Unused JITStubArg args[6]; @@ -149,13 +149,15 @@ namespace JSC { CallFrame* callFrame; JSValue* exception; + void* padding2; + // These arguments passed on the stack. Profiler** enabledProfilerReference; JSGlobalData* globalData; ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; -#elif PLATFORM(ARM) +#elif PLATFORM(ARM_TRADITIONAL) struct JITStackFrame { JITStubArg padding; // Unused JITStubArg args[7]; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp index 14a398a..3bd318a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp @@ -1886,10 +1886,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData) , ParserArenaRefCounted(globalData) , m_features(NoFeatures) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif } ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants) @@ -1899,10 +1895,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceE , m_features(features) , m_source(source) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif } inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst) diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h b/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h index 84360b8..9ba4da3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h @@ -37,7 +37,8 @@ namespace JSC { class SourceCode { public: SourceCode() - : m_startChar(0) + : m_provider(0) + , m_startChar(0) , m_endChar(0) , m_firstLine(0) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BatchedTransitionOptimizer.h index b9f738f..929a5e7 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/BatchedTransitionOptimizer.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BatchedTransitionOptimizer.h @@ -38,7 +38,7 @@ namespace JSC { : m_object(object) { if (!m_object->structure()->isDictionary()) - m_object->setStructure(Structure::toDictionaryTransition(m_object->structure())); + m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure())); } ~BatchedTransitionOptimizer() diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h index 8493d73..abe5038 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h @@ -39,6 +39,9 @@ macro(compile) \ macro(configurable) \ macro(constructor) \ + macro(create) \ + macro(defineProperty) \ + macro(defineProperties) \ macro(enumerable) \ macro(eval) \ macro(exec) \ diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp index f36de54..ec3e000 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp @@ -37,7 +37,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source) { JSLock lock(exec); - ProgramExecutable program(source); + ProgramExecutable program(exec, source); JSObject* error = program.checkSyntax(exec); if (error) return Completion(Throw, error); @@ -49,7 +49,7 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s { JSLock lock(exec); - ProgramExecutable program(source); + ProgramExecutable program(exec, source); JSObject* error = program.compile(exec, scopeChain.node()); if (error) return Completion(Throw, error); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.cpp index 5e79794..7586746 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.cpp @@ -259,7 +259,7 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); ASSERT(body); - return FunctionExecutable::create(functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); } UString FunctionExecutable::paramString() const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.h index d437d46..9728775 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Executable.h @@ -27,7 +27,9 @@ #define Executable_h #include "JSFunction.h" +#include "Interpreter.h" #include "Nodes.h" +#include "SamplingTool.h" namespace JSC { @@ -102,11 +104,30 @@ namespace JSC { class ScriptExecutable : public ExecutableBase { public: - ScriptExecutable(const SourceCode& source) + ScriptExecutable(JSGlobalData* globalData, const SourceCode& source) : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) , m_source(source) , m_features(0) { +#if ENABLE(CODEBLOCK_SAMPLING) + if (SamplingTool* sampler = globalData->interpreter->sampler()) + sampler->notifyOfScope(this); +#else + UNUSED_PARAM(globalData); +#endif + } + + ScriptExecutable(ExecState* exec, const SourceCode& source) + : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) + , m_source(source) + , m_features(0) + { +#if ENABLE(CODEBLOCK_SAMPLING) + if (SamplingTool* sampler = exec->globalData().interpreter->sampler()) + sampler->notifyOfScope(this); +#else + UNUSED_PARAM(exec); +#endif } const SourceCode& source() { return m_source; } @@ -137,8 +158,8 @@ namespace JSC { class EvalExecutable : public ScriptExecutable { public: - EvalExecutable(const SourceCode& source) - : ScriptExecutable(source) + EvalExecutable(ExecState* exec, const SourceCode& source) + : ScriptExecutable(exec, source) , m_evalCodeBlock(0) { } @@ -157,7 +178,7 @@ namespace JSC { JSObject* compile(ExecState*, ScopeChainNode*); ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*); - static PassRefPtr<EvalExecutable> create(const SourceCode& source) { return adoptRef(new EvalExecutable(source)); } + static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); } private: EvalCodeBlock* m_evalCodeBlock; @@ -178,8 +199,8 @@ namespace JSC { class ProgramExecutable : public ScriptExecutable { public: - ProgramExecutable(const SourceCode& source) - : ScriptExecutable(source) + ProgramExecutable(ExecState* exec, const SourceCode& source) + : ScriptExecutable(exec, source) , m_programCodeBlock(0) { } @@ -221,9 +242,14 @@ namespace JSC { class FunctionExecutable : public ScriptExecutable { friend class JIT; public: - static PassRefPtr<FunctionExecutable> create(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + { + return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine)); + } + + static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) { - return adoptRef(new FunctionExecutable(name, source, forceUsesArguments, parameters, firstLine, lastLine)); + return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine)); } ~FunctionExecutable(); @@ -263,8 +289,20 @@ namespace JSC { static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); private: - FunctionExecutable(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) - : ScriptExecutable(source) + FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + : ScriptExecutable(globalData, source) + , m_forceUsesArguments(forceUsesArguments) + , m_parameters(parameters) + , m_codeBlock(0) + , m_name(name) + , m_numVariables(0) + { + m_firstLine = firstLine; + m_lastLine = lastLine; + } + + FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + : ScriptExecutable(exec, source) , m_forceUsesArguments(forceUsesArguments) , m_parameters(parameters) , m_codeBlock(0) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp index 1fcca81..101f543 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -223,7 +223,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot } } - return false; + return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, i), slot); } bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp index 3a1909d..8d71ac3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -175,18 +175,18 @@ void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& proper } } -void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc) +void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) { PropertySlot slot; if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineGetter(exec, propertyName, getterFunc); + JSVariableObject::defineGetter(exec, propertyName, getterFunc, attributes); } -void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc) +void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) { PropertySlot slot; if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineSetter(exec, propertyName, setterFunc); + JSVariableObject::defineSetter(exec, propertyName, setterFunc, attributes); } static inline JSObject* lastInPrototypeChain(JSObject* object) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h index d1150cc..5f7137f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h @@ -175,8 +175,8 @@ namespace JSC { virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes); - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes); // Linked list of all global objects that use the same JSGlobalData. JSGlobalObject*& head() { return d()->globalData->head; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index b11070f..5ded370 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -286,7 +286,7 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; - EvalExecutable eval(makeSource(s)); + EvalExecutable eval(exec, makeSource(s)); JSObject* error = eval.compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node()); if (error) return throwError(exec, error); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp index f910603..74af4b1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp @@ -275,7 +275,7 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi return 0; } -void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { JSValue object = getDirect(propertyName); if (object && object.isGetterSetter()) { @@ -286,7 +286,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO PutPropertySlot slot; GetterSetter* getterSetter = new (exec) GetterSetter(exec); - putDirectInternal(exec->globalData(), propertyName, getterSetter, Getter, true, slot); + putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, true, slot); // putDirect will change our Structure if we add a new property. For // getters and setters, though, we also need to change our Structure @@ -302,7 +302,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO getterSetter->setGetter(getterFunction); } -void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { JSValue object = getDirect(propertyName); if (object && object.isGetterSetter()) { @@ -313,7 +313,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO PutPropertySlot slot; GetterSetter* getterSetter = new (exec) GetterSetter(exec); - putDirectInternal(exec->globalData(), propertyName, getterSetter, Setter, true, slot); + putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot); // putDirect will change our Structure if we add a new property. For // getters and setters, though, we also need to change our Structure @@ -471,7 +471,7 @@ JSObject* JSObject::unwrappedObject() void JSObject::removeDirect(const Identifier& propertyName) { size_t offset; - if (m_structure->isDictionary()) { + if (m_structure->isUncacheableDictionary()) { offset = m_structure->removePropertyWithoutTransition(propertyName); if (offset != WTF::notFound) putDirectOffset(offset, jsUndefined()); @@ -541,4 +541,131 @@ bool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& property object = asObject(prototype); } } + +static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, JSValue oldValue) +{ + if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) { + target->putWithAttributes(exec, propertyName, descriptor.value() ? descriptor.value() : oldValue, attributes & ~(Getter | Setter)); + return true; + } + attributes &= ~ReadOnly; + if (descriptor.getter() && descriptor.getter().isObject()) + target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes); + if (exec->hadException()) + return false; + if (descriptor.setter() && descriptor.setter().isObject()) + target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes); + return !exec->hadException(); +} + +bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) +{ + // If we have a new property we can just put it on normally + PropertyDescriptor current; + if (!getOwnPropertyDescriptor(exec, propertyName, current)) + return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), jsUndefined()); + + if (descriptor.isEmpty()) + return true; + + if (current.equalTo(descriptor)) + return true; + + // Filter out invalid changes + if (!current.configurable()) { + if (descriptor.configurable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to configurable attribute of unconfigurable property."); + return false; + } + if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change enumerable attribute of unconfigurable property."); + return false; + } + } + + // A generic descriptor is simply changing the attributes of an existing property + if (descriptor.isGenericDescriptor()) { + if (!current.attributesEqual(descriptor)) { + deleteProperty(exec, propertyName); + putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); + } + return true; + } + + // Changing between a normal property or an accessor property + if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { + if (!current.configurable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change access mechanism for an unconfigurable property."); + return false; + } + deleteProperty(exec, propertyName); + return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value() ? current.value() : jsUndefined()); + } + + // Changing the value and attributes of an existing property + if (descriptor.isDataDescriptor()) { + if (!current.configurable()) { + if (!current.writable() && descriptor.writable()) { + if (throwException) + throwError(exec, TypeError, "Attempting to change writable attribute of unconfigurable property."); + return false; + } + if (!current.writable()) { + if (descriptor.value() || !JSValue::strictEqual(current.value(), descriptor.value())) { + if (throwException) + throwError(exec, TypeError, "Attempting to change value of a readonly property."); + return false; + } + } + } else if (current.attributesEqual(descriptor)) { + if (!descriptor.value()) + return true; + PutPropertySlot slot; + put(exec, propertyName, descriptor.value(), slot); + if (exec->hadException()) + return false; + return true; + } + deleteProperty(exec, propertyName); + return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); + } + + // Changing the accessor functions of an existing accessor property + ASSERT(descriptor.isAccessorDescriptor()); + if (!current.configurable()) { + if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(current.setter(), descriptor.setter()))) { + if (throwException) + throwError(exec, TypeError, "Attempting to change the setter of an unconfigurable property."); + return false; + } + if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(current.getter(), descriptor.getter()))) { + if (throwException) + throwError(exec, TypeError, "Attempting to change the getter of an unconfigurable property."); + return false; + } + } + JSValue accessor = getDirect(propertyName); + if (!accessor) + return false; + GetterSetter* getterSetter = asGetterSetter(accessor); + if (current.attributesEqual(descriptor)) { + if (descriptor.setter()) + getterSetter->setSetter(asObject(descriptor.setter())); + if (descriptor.getter()) + getterSetter->setGetter(asObject(descriptor.getter())); + return true; + } + deleteProperty(exec, propertyName); + unsigned attrs = current.attributesWithOverride(descriptor); + if (descriptor.setter()) + attrs |= Setter; + if (descriptor.getter()) + attrs |= Getter; + putDirect(propertyName, getterSetter, attrs); + return true; +} + } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h index bdc949b..3fd1e3c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h @@ -186,10 +186,11 @@ namespace JSC { void fillGetterPropertySlot(PropertySlot&, JSValue* location); - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction); + virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0); + virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0); virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); + virtual bool defineOwnProperty(ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow); virtual bool isGlobalObject() const { return false; } virtual bool isVariableObject() const { return false; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStackPosix.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStackPosix.cpp index 8e78ff3..43f8b29 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStackPosix.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStackPosix.cpp @@ -29,22 +29,44 @@ #include "MarkStack.h" #include <unistd.h> +#if defined (__SYMBIAN32__) +#include "wtf/FastMalloc.h" +#include <e32base.h> +#include <e32std.h> +#include <e32hal.h> +#include <hal.h> +#else #include <sys/mman.h> +#endif namespace JSC { void MarkStack::initializePagesize() { +#if defined (__SYMBIAN32__) + TInt page_size; + UserHal::PageSizeInBytes(page_size); + MarkStack::s_pageSize = page_size; +#else MarkStack::s_pageSize = getpagesize(); +#endif } void* MarkStack::allocateStack(size_t size) { +#if defined (__SYMBIAN32__) + return fastMalloc(size); +#else return mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +#endif } void MarkStack::releaseStack(void* addr, size_t size) { +#if defined (__SYMBIAN32__) + fastFree(addr); +#else munmap(addr, size); +#endif } } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp index fd45c45..2992f1b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -37,6 +37,9 @@ ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor); static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorCreate(ExecState*, JSObject*, JSValue, const ArgList&); ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure) : InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object")) @@ -50,6 +53,9 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> stru putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().create, objectConstructorCreate), DontEnum); } // ECMA 15.2.2 @@ -103,15 +109,14 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, return jsUndefined(); if (exec->hadException()) return jsUndefined(); - ASSERT(descriptor.isValid()); JSObject* description = constructEmptyObject(exec); - if (!descriptor.hasAccessors()) { - description->putDirect(exec->propertyNames().value, descriptor.value(), 0); + if (!descriptor.isAccessorDescriptor()) { + description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0); description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0); } else { - description->putDirect(exec->propertyNames().get, descriptor.getter(), 0); - description->putDirect(exec->propertyNames().set, descriptor.setter(), 0); + description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0); + description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0); } description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0); @@ -133,4 +138,163 @@ JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, return keys; } +// ES5 8.10.5 ToPropertyDescriptor +static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc) +{ + if (!in.isObject()) { + throwError(exec, TypeError, "Property description must be an object."); + return false; + } + JSObject* description = asObject(in); + + PropertySlot enumerableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) { + desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + PropertySlot configurableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) { + desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + JSValue value; + PropertySlot valueSlot; + if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) { + desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value)); + if (exec->hadException()) + return false; + } + + PropertySlot writableSlot; + if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) { + desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec)); + if (exec->hadException()) + return false; + } + + PropertySlot getSlot; + if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) { + JSValue get = getSlot.getValue(exec, exec->propertyNames().get); + if (exec->hadException()) + return false; + if (!get.isUndefined()) { + CallData callData; + if (get.getCallData(callData) == CallTypeNone) { + throwError(exec, TypeError, "Getter must be a function."); + return false; + } + } else + get = JSValue(); + desc.setGetter(get); + } + + PropertySlot setSlot; + if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) { + JSValue set = setSlot.getValue(exec, exec->propertyNames().set); + if (exec->hadException()) + return false; + if (!set.isUndefined()) { + CallData callData; + if (set.getCallData(callData) == CallTypeNone) { + throwError(exec, TypeError, "Setter must be a function."); + return false; + } + } else + set = JSValue(); + + desc.setSetter(set); + } + + if (!desc.isAccessorDescriptor()) + return true; + + if (desc.value()) { + throwError(exec, TypeError, "Invalid property. 'value' present on property with getter or setter."); + return false; + } + + if (desc.writablePresent()) { + throwError(exec, TypeError, "Invalid property. 'writable' present on property with getter or setter."); + return false; + } + return true; +} + +JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Properties can only be defined on Objects."); + JSObject* O = asObject(args.at(0)); + UString propertyName = args.at(1).toString(exec); + if (exec->hadException()) + return jsNull(); + PropertyDescriptor descriptor; + if (!toPropertyDescriptor(exec, args.at(2), descriptor)) + return jsNull(); + ASSERT((descriptor.attributes() & (Getter | Setter)) || (!descriptor.isAccessorDescriptor())); + ASSERT(!exec->hadException()); + O->defineOwnProperty(exec, Identifier(exec, propertyName), descriptor, true); + return O; +} + +static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties) +{ + PropertyNameArray propertyNames(exec); + asObject(properties)->getOwnPropertyNames(exec, propertyNames); + size_t numProperties = propertyNames.size(); + Vector<PropertyDescriptor> descriptors; + MarkedArgumentBuffer markBuffer; + for (size_t i = 0; i < numProperties; i++) { + PropertySlot slot; + JSValue prop = properties->get(exec, propertyNames[i]); + if (exec->hadException()) + return jsNull(); + PropertyDescriptor descriptor; + if (!toPropertyDescriptor(exec, prop, descriptor)) + return jsNull(); + descriptors.append(descriptor); + // Ensure we mark all the values that we're accumulating + if (descriptor.isDataDescriptor() && descriptor.value()) + markBuffer.append(descriptor.value()); + if (descriptor.isAccessorDescriptor()) { + if (descriptor.getter()) + markBuffer.append(descriptor.getter()); + if (descriptor.setter()) + markBuffer.append(descriptor.setter()); + } + } + for (size_t i = 0; i < numProperties; i++) { + object->defineOwnProperty(exec, propertyNames[i], descriptors[i], true); + if (exec->hadException()) + return jsNull(); + } + return object; +} + +JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Properties can only be defined on Objects."); + if (!args.at(1).isObject()) + return throwError(exec, TypeError, "Property descriptor list must be an Object."); + return defineProperties(exec, asObject(args.at(0)), asObject(args.at(1))); +} + +JSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject() && !args.at(0).isNull()) + return throwError(exec, TypeError, "Object prototype may only be an Object or null."); + JSObject* newObject = constructEmptyObject(exec); + newObject->setPrototype(args.at(0)); + if (args.at(1).isUndefined()) + return newObject; + if (!args.at(1).isObject()) + return throwError(exec, TypeError, "Property descriptor list must be an Object."); + return defineProperties(exec, newObject, asObject(args.at(1))); +} + } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.cpp index d892e0a..4db814f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.cpp @@ -30,29 +30,40 @@ #include "GetterSetter.h" #include "JSObject.h" +#include "Operations.h" namespace JSC { +unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1; + bool PropertyDescriptor::writable() const { - ASSERT(!hasAccessors()); + ASSERT(!isAccessorDescriptor()); return !(m_attributes & ReadOnly); } bool PropertyDescriptor::enumerable() const { - ASSERT(isValid()); return !(m_attributes & DontEnum); } bool PropertyDescriptor::configurable() const { - ASSERT(isValid()); return !(m_attributes & DontDelete); } -bool PropertyDescriptor::hasAccessors() const +bool PropertyDescriptor::isDataDescriptor() const { - return !!(m_attributes & (Getter | Setter)); + return m_value || (m_seenAttributes & WritablePresent); +} + +bool PropertyDescriptor::isGenericDescriptor() const +{ + return !isAccessorDescriptor() && !isDataDescriptor(); +} + +bool PropertyDescriptor::isAccessorDescriptor() const +{ + return m_getter || m_setter; } void PropertyDescriptor::setUndefined() @@ -63,32 +74,31 @@ void PropertyDescriptor::setUndefined() JSValue PropertyDescriptor::getter() const { - ASSERT(hasAccessors()); - if (!m_getter) - return jsUndefined(); + ASSERT(isAccessorDescriptor()); return m_getter; } JSValue PropertyDescriptor::setter() const { - ASSERT(hasAccessors()); - if (!m_setter) - return jsUndefined(); + ASSERT(isAccessorDescriptor()); return m_setter; } void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) { ASSERT(value); + m_attributes = attributes; if (attributes & (Getter | Setter)) { GetterSetter* accessor = asGetterSetter(value); m_getter = accessor->getter(); m_setter = accessor->setter(); ASSERT(m_getter || m_setter); + m_seenAttributes = EnumerablePresent | ConfigurablePresent; + m_attributes &= ~ReadOnly; } else { m_value = value; + m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; } - m_attributes = attributes; } void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes) @@ -98,6 +108,88 @@ void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, u m_attributes = attributes; m_getter = getter; m_setter = setter; + m_attributes &= ~ReadOnly; + m_seenAttributes = EnumerablePresent | ConfigurablePresent; +} + +void PropertyDescriptor::setWritable(bool writable) +{ + if (writable) + m_attributes &= ~ReadOnly; + else + m_attributes |= ReadOnly; + m_seenAttributes |= WritablePresent; +} + +void PropertyDescriptor::setEnumerable(bool enumerable) +{ + if (enumerable) + m_attributes &= ~DontEnum; + else + m_attributes |= DontEnum; + m_seenAttributes |= EnumerablePresent; +} + +void PropertyDescriptor::setConfigurable(bool configurable) +{ + if (configurable) + m_attributes &= ~DontDelete; + else + m_attributes |= DontDelete; + m_seenAttributes |= ConfigurablePresent; +} + +void PropertyDescriptor::setSetter(JSValue setter) +{ + m_setter = setter; + m_attributes |= Setter; + m_attributes &= ~ReadOnly; +} + +void PropertyDescriptor::setGetter(JSValue getter) +{ + m_getter = getter; + m_attributes |= Getter; + m_attributes &= ~ReadOnly; +} + +bool PropertyDescriptor::equalTo(const PropertyDescriptor& other) const +{ + if (!other.m_value == m_value || + !other.m_getter == m_getter || + !other.m_setter == m_setter) + return false; + return (!m_value || JSValue::strictEqual(other.m_value, m_value)) && + (!m_getter || JSValue::strictEqual(other.m_getter, m_getter)) && + (!m_setter || JSValue::strictEqual(other.m_setter, m_setter)) && + attributesEqual(other); +} + +bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const +{ + unsigned mismatch = other.m_attributes ^ m_attributes; + unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; + if (sharedSeen & WritablePresent && mismatch & ReadOnly) + return false; + if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) + return false; + if (sharedSeen & EnumerablePresent && mismatch & DontEnum) + return false; + return true; +} + +unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const +{ + unsigned mismatch = other.m_attributes ^ m_attributes; + unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; + unsigned newAttributes = m_attributes & defaultAttributes; + if (sharedSeen & WritablePresent && mismatch & ReadOnly) + newAttributes ^= ReadOnly; + if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) + newAttributes ^= DontDelete; + if (sharedSeen & EnumerablePresent && mismatch & DontEnum) + newAttributes ^= DontEnum; + return newAttributes; } } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.h index ad7c056..40bec86 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyDescriptor.h @@ -32,29 +32,48 @@ namespace JSC { class PropertyDescriptor { public: PropertyDescriptor() - : m_attributes(0) + : m_attributes(defaultAttributes) + , m_seenAttributes(0) { } bool writable() const; bool enumerable() const; bool configurable() const; - bool hasAccessors() const; + bool isDataDescriptor() const; + bool isGenericDescriptor() const; + bool isAccessorDescriptor() const; unsigned attributes() const { return m_attributes; } -#ifndef NDEBUG - bool isValid() const { return m_value || ((m_getter || m_setter) && hasAccessors()); } -#endif - JSValue value() const { ASSERT(m_value); return m_value; } + JSValue value() const { return m_value; } JSValue getter() const; JSValue setter() const; void setUndefined(); void setDescriptor(JSValue value, unsigned attributes); void setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes); + void setWritable(bool); + void setEnumerable(bool); + void setConfigurable(bool); + void setValue(JSValue value) { m_value = value; } + void setSetter(JSValue); + void setGetter(JSValue); + bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); } + bool writablePresent() const { return m_seenAttributes & WritablePresent; } + bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; } + bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; } + bool setterPresent() const { return m_setter; } + bool getterPresent() const { return m_getter; } + bool equalTo(const PropertyDescriptor& other) const; + bool attributesEqual(const PropertyDescriptor& other) const; + unsigned attributesWithOverride(const PropertyDescriptor& other) const; private: + static unsigned defaultAttributes; + bool operator==(const PropertyDescriptor&){ return false; } + enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4}; // May be a getter/setter JSValue m_value; JSValue m_getter; JSValue m_setter; unsigned m_attributes; + unsigned m_seenAttributes; }; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp index 34c27b7..7209b5f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp @@ -127,7 +127,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo) , m_propertyTable(0) , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) , m_offset(noOffset) - , m_isDictionary(false) + , m_dictionaryKind(NoneDictionaryKind) , m_isPinnedPropertyTable(false) , m_hasGetterSetterProperties(false) , m_attributesInPrevious(0) @@ -290,7 +290,7 @@ void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) { - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary); + bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); if (shouldCache && m_cachedPropertyNameArrayData) { if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { @@ -349,7 +349,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) materializePropertyMapIfNecessary(); - ASSERT(m_isDictionary); + ASSERT(isDictionary()); ASSERT(m_propertyTable); unsigned i = rep->computedHash(); @@ -391,7 +391,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); if (Structure* existingTransition = structure->table.get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) { @@ -405,12 +405,12 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); if (structure->transitionCount() > s_maxTransitionLength) { - RefPtr<Structure> transition = toDictionaryTransition(structure); + RefPtr<Structure> transition = toCacheableDictionaryTransition(structure); ASSERT(structure != transition); offset = transition->put(propertyName, attributes, specificValue); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) @@ -454,9 +454,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset) { - ASSERT(!structure->m_isDictionary); + ASSERT(!structure->isUncacheableDictionary()); - RefPtr<Structure> transition = toDictionaryTransition(structure); + RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure); offset = transition->remove(propertyName); @@ -554,25 +554,35 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) return transition.release(); } -PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure) +PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind) { - ASSERT(!structure->m_isDictionary); - + ASSERT(!structure->isUncacheableDictionary()); + RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); - transition->m_isDictionary = true; + transition->m_dictionaryKind = kind; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - + structure->materializePropertyMapIfNecessary(); transition->m_propertyTable = structure->copyPropertyTable(); transition->m_isPinnedPropertyTable = true; - + return transition.release(); } +PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure) +{ + return toDictionaryTransition(structure, CachedDictionaryKind); +} + +PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure) +{ + return toDictionaryTransition(structure, UncachedDictionaryKind); +} + PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) { - ASSERT(structure->m_isDictionary); + ASSERT(structure->isDictionary()); // Since dictionary Structures are not shared, and no opcodes specialize // for them, we don't need to allocate a new Structure when transitioning @@ -581,7 +591,7 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the // deleted offsets vector) before transitioning from dictionary. if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty()) - structure->m_isDictionary = false; + structure->m_dictionaryKind = NoneDictionaryKind; return structure; } @@ -600,7 +610,7 @@ size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, u size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { - ASSERT(m_isDictionary); + ASSERT(isUncacheableDictionary()); materializePropertyMapIfNecessary(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index f7cb04b..ed9f6e5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -70,7 +70,8 @@ namespace JSC { static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&); static PassRefPtr<Structure> addAnonymousSlotsTransition(Structure*, unsigned count); static PassRefPtr<Structure> getterSetterTransition(Structure*); - static PassRefPtr<Structure> toDictionaryTransition(Structure*); + static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*); + static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*); static PassRefPtr<Structure> fromDictionaryTransition(Structure*); ~Structure(); @@ -81,8 +82,9 @@ namespace JSC { size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t removePropertyWithoutTransition(const Identifier& propertyName); void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; } - - bool isDictionary() const { return m_isDictionary; } + + bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; } + bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; } const TypeInfo& typeInfo() const { return m_typeInfo; } @@ -127,6 +129,13 @@ namespace JSC { private: Structure(JSValue prototype, const TypeInfo&); + + typedef enum { + NoneDictionaryKind = 0, + CachedDictionaryKind = 1, + UncachedDictionaryKind = 2 + } DictionaryKind; + static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind); size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); @@ -187,7 +196,7 @@ namespace JSC { size_t m_propertyStorageCapacity; signed char m_offset; - bool m_isDictionary : 1; + unsigned m_dictionaryKind : 2; bool m_isPinnedPropertyTable : 1; bool m_hasGetterSetterProperties : 1; #if COMPILER(WINSCW) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp index eb57a5ac..6e8a0ee 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp @@ -51,6 +51,7 @@ 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()) diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h index 59efd84..b68e70c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h @@ -144,7 +144,13 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #if ASSERT_DISABLED #define ASSERT(assertion) ((void)0) +#if COMPILER(MSVC7) +#define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif PLATFORM(SYMBIAN) +#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) +#else #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) +#endif /* COMPILER(MSVC7) */ #define ASSERT_NOT_REACHED() ((void)0) #define ASSERT_UNUSED(variable, assertion) ((void)variable) @@ -158,6 +164,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann while (0) #if COMPILER(MSVC7) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif PLATFORM(SYMBIAN) +#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) do \ if (!(assertion)) { \ @@ -199,10 +207,12 @@ while (0) /* FATAL */ -#if FATAL_DISABLED +#if FATAL_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define FATAL(...) ((void)0) #elif COMPILER(MSVC7) #define FATAL() ((void)0) +#elif PLATFORM(SYMBIAN) +#define FATAL(args...) ((void)0) #else #define FATAL(...) do { \ WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \ @@ -212,20 +222,24 @@ while (0) /* LOG_ERROR */ -#if ERROR_DISABLED +#if ERROR_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG_ERROR(...) ((void)0) #elif COMPILER(MSVC7) #define LOG_ERROR() ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG_ERROR(args...) ((void)0) #else #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) #endif /* LOG */ -#if LOG_DISABLED +#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG(channel, ...) ((void)0) #elif COMPILER(MSVC7) #define LOG() ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG(channel, args...) ((void)0) #else #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) @@ -234,10 +248,12 @@ while (0) /* LOG_VERBOSE */ -#if LOG_DISABLED +#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) #define LOG_VERBOSE(channel, ...) ((void)0) #elif COMPILER(MSVC7) #define LOG_VERBOSE(channel) ((void)0) +#elif PLATFORM(SYMBIAN) +#define LOG_VERBOSE(channel, args...) ((void)0) #else #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Forward.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Forward.h index 67dc3be..448de7d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Forward.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Forward.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,6 +27,7 @@ namespace WTF { template<typename T> class ListRefPtr; template<typename T> class OwnArrayPtr; template<typename T> class OwnPtr; + template<typename T> class PassOwnPtr; template<typename T> class PassRefPtr; template<typename T> class RefPtr; template<typename T, size_t inlineCapacity> class Vector; @@ -35,9 +36,9 @@ namespace WTF { using WTF::ListRefPtr; using WTF::OwnArrayPtr; using WTF::OwnPtr; +using WTF::PassOwnPtr; using WTF::PassRefPtr; using WTF::RefPtr; using WTF::Vector; #endif // WTF_Forward_h - diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/HashCountedSet.h b/src/3rdparty/webkit/JavaScriptCore/wtf/HashCountedSet.h index 1a422d8..1fda9c1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/HashCountedSet.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/HashCountedSet.h @@ -64,8 +64,13 @@ namespace WTF { void remove(const ValueType& value); void remove(iterator it); - void clear(); - + // removes the value, regardless of its count + void clear(iterator it); + void clear(const ValueType& value); + + // clears the whole set + void clear(); + private: ImplType m_impl; }; @@ -166,6 +171,21 @@ namespace WTF { } template<typename Value, typename HashFunctions, typename Traits> + inline void HashCountedSet<Value, HashFunctions, Traits>::clear(const ValueType& value) + { + clear(find(value)); + } + + template<typename Value, typename HashFunctions, typename Traits> + inline void HashCountedSet<Value, HashFunctions, Traits>::clear(iterator it) + { + if (it == end()) + return; + + m_impl.remove(it); + } + + template<typename Value, typename HashFunctions, typename Traits> inline void HashCountedSet<Value, HashFunctions, Traits>::clear() { m_impl.clear(); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h index 9f9a354..d863226 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h @@ -34,13 +34,8 @@ namespace WTF { ListRefPtr(const RefPtr<T>& o) : RefPtr<T>(o) {} // see comment in PassRefPtr.h for why this takes const reference template <typename U> ListRefPtr(const PassRefPtr<U>& o) : RefPtr<T>(o) {} - - ~ListRefPtr() - { - RefPtr<T> reaper = this->release(); - while (reaper && reaper->hasOneRef()) - reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper - } + + ~ListRefPtr(); ListRefPtr& operator=(T* optr) { RefPtr<T>::operator=(optr); return *this; } ListRefPtr& operator=(const RefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; } @@ -49,6 +44,17 @@ namespace WTF { template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } }; + template <typename T> +#if !COMPILER(WINSCW) + inline +#endif + ListRefPtr<T>::~ListRefPtr() + { + RefPtr<T> reaper = this->release(); + while (reaper && reaper->hasOneRef()) + reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper + } + template <typename T> inline T* getPtr(const ListRefPtr<T>& p) { return p.get(); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h index 2abf3d2..e508f77 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h @@ -226,8 +226,11 @@ #endif /* PLATFORM(ARM) */ +#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) + #if defined(arm) \ - || defined(__arm__) + || defined(__arm__) \ + || defined(__MARM__) #define WTF_PLATFORM_ARM 1 #if defined(__ARMEB__) #define WTF_PLATFORM_BIG_ENDIAN 1 @@ -241,22 +244,35 @@ #endif #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) + || defined(__ARM_ARCH_5TEJ__) || defined(__MARM_ARMV5__) #undef ARM_ARCH_VERSION #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(__ARM_ARCH_6ZK__) || defined(__ARMV6__) #undef ARM_ARCH_VERSION #define ARM_ARCH_VERSION 6 #endif -#if defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7A__) || defined(__ARMV7__) #undef ARM_ARCH_VERSION #define ARM_ARCH_VERSION 7 #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__) +# define WTF_PLATFORM_ARM_TRADITIONAL 0 +# define WTF_PLATFORM_ARM_THUMB2 1 +# elif PLATFORM_ARM_ARCH(4) || PLATFORM_ARM_ARCH(5) +# define WTF_PLATFORM_ARM_TRADITIONAL 1 +# define WTF_PLATFORM_ARM_THUMB2 0 +# else +# error "Not supported ARM architecture" +# endif +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(ARM_THUMB2) /* Sanity Check */ +# error "Cannot use both of WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 platforms" +#endif // !defined(ARM_TRADITIONAL) && !defined(ARM_THUMB2) #endif /* ARM */ -#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) /* PLATFORM(X86) */ #if defined(__i386__) \ @@ -392,6 +408,9 @@ #if PLATFORM(MAC) && !PLATFORM(IPHONE) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && defined(__x86_64__) +#define WTF_USE_PLUGIN_HOST_PROCESS 1 +#endif #if !defined(ENABLE_MAC_JAVA_BRIDGE) #define ENABLE_MAC_JAVA_BRIDGE 1 #endif @@ -400,7 +419,7 @@ #endif #define HAVE_READLINE 1 #define HAVE_RUNLOOP_TIMER 1 -#endif +#endif // PLATFORM(MAC) && !PLATFORM(IPHONE) #if PLATFORM(CHROMIUM) && PLATFORM(DARWIN) #define WTF_PLATFORM_CF 1 @@ -408,18 +427,19 @@ #endif #if PLATFORM(IPHONE) -#define WTF_PLATFORM_CF 1 -#define WTF_USE_PTHREADS 1 #define ENABLE_CONTEXT_MENUS 0 #define ENABLE_DRAG_SUPPORT 0 #define ENABLE_FTPDIR 1 +#define ENABLE_GEOLOCATION 1 +#define ENABLE_ICONDATABASE 0 #define ENABLE_INSPECTOR 0 #define ENABLE_MAC_JAVA_BRIDGE 0 -#define ENABLE_ICONDATABASE 0 -#define ENABLE_GEOLOCATION 1 #define ENABLE_NETSCAPE_PLUGIN_API 0 -#define HAVE_READLINE 1 +#define ENABLE_ORIENTATION_EVENTS 1 #define ENABLE_REPAINT_THROTTLING 1 +#define HAVE_READLINE 1 +#define WTF_PLATFORM_CF 1 +#define WTF_USE_PTHREADS 1 #endif #if PLATFORM(WIN) @@ -579,6 +599,14 @@ #define ENABLE_NETSCAPE_PLUGIN_API 1 #endif +#if !defined(WTF_USE_PLUGIN_HOST_PROCESS) +#define WTF_USE_PLUGIN_HOST_PROCESS 0 +#endif + +#if !defined(ENABLE_ORIENTATION_EVENTS) +#define ENABLE_ORIENTATION_EVENTS 0 +#endif + #if !defined(ENABLE_OPCODE_STATS) #define ENABLE_OPCODE_STATS 0 #endif @@ -637,7 +665,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #elif PLATFORM(X86) && PLATFORM(MAC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) +#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_OPTIMIZE_NATIVE_CALL 0 @@ -656,8 +684,11 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #elif PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100 #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) && PLATFORM(LINUX) +#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) #define ENABLE_JIT 1 + #if PLATFORM(ARM_THUMB2) + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 + #endif #endif #endif /* PLATFORM(QT) */ @@ -703,7 +734,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #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_ARCH(7) && PLATFORM(IPHONE) && 0) \ + || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) && 0) \ || (PLATFORM(X86) && PLATFORM(WIN)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 @@ -713,7 +744,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #if (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ || (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC)) \ || (PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100) \ - || (PLATFORM(ARM) && !PLATFORM_ARM_ARCH(7) && PLATFORM(LINUX)) + || (PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/RefPtr.h b/src/3rdparty/webkit/JavaScriptCore/wtf/RefPtr.h index 77835ad..1a0b1fe 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/RefPtr.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/RefPtr.h @@ -50,7 +50,7 @@ namespace WTF { ~RefPtr() { T* ptr = m_ptr; derefIfNotNull(ptr); } - template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); } + template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(static_cast<T*>(o.get())) { if (T* ptr = static_cast<T*>(m_ptr)) ptr->ref(); } T* get() const { return m_ptr; } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Vector.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Vector.h index 7cba4e4..e1fc5b4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Vector.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Vector.h @@ -63,6 +63,13 @@ namespace WTF { template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); }; template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); }; + template <size_t size, size_t alignment> + void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b) + { + for (size_t i = 0; i < size; ++i) + std::swap(a.buffer[i], b.buffer[i]); + } + template <bool needsDestruction, typename T> class VectorDestructor; @@ -404,6 +411,27 @@ namespace WTF { Base::deallocateBuffer(bufferToDeallocate); } + void swap(VectorBuffer<T, inlineCapacity>& other) + { + if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) { + WTF::swap(m_inlineBuffer, other.m_inlineBuffer); + std::swap(m_capacity, other.m_capacity); + } else if (buffer() == inlineBuffer()) { + m_buffer = other.m_buffer; + other.m_buffer = other.inlineBuffer(); + WTF::swap(m_inlineBuffer, other.m_inlineBuffer); + std::swap(m_capacity, other.m_capacity); + } else if (other.buffer() == other.inlineBuffer()) { + other.m_buffer = m_buffer; + m_buffer = inlineBuffer(); + WTF::swap(m_inlineBuffer, other.m_inlineBuffer); + std::swap(m_capacity, other.m_capacity); + } else { + std::swap(m_buffer, other.m_buffer); + std::swap(m_capacity, other.m_capacity); + } + } + void restoreInlineBufferIfNeeded() { if (m_buffer) diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/unicode/Unicode.h b/src/3rdparty/webkit/JavaScriptCore/wtf/unicode/Unicode.h index d59439d..7016a03 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/unicode/Unicode.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/unicode/Unicode.h @@ -26,7 +26,11 @@ #include <wtf/Assertions.h> #if USE(QT4_UNICODE) +#if COMPILER(WINSCW) || COMPILER(RVCT) +#include "wtf/unicode/qt4/UnicodeQt4.h" +#else #include "qt4/UnicodeQt4.h" +#endif #elif USE(ICU_UNICODE) #include <wtf/unicode/icu/UnicodeIcu.h> #elif USE(GLIB_UNICODE) diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp index 16b1ecc..4390b5b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp @@ -1309,7 +1309,7 @@ class RegexGenerator : private MacroAssembler { loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif #elif PLATFORM(ARM) -#if !PLATFORM_ARM_ARCH(7) +#if PLATFORM(ARM_TRADITIONAL) push(ARMRegisters::lr); #endif push(ARMRegisters::r4); diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 16d854d..e13219b 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,8 +4,8 @@ This is a snapshot of the Qt port of WebKit from The commit imported was from the - origin/qtwebkit-4.6-staging branch/tag + qtwebkit-4.6-snapshot-24092009 branch/tag and has the sha1 checksum - f572f72dce91be9a4525941c87d1b0a8c383ba39 + 75c44947a340d74a9e0098a3dfffabce0c9512ef diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 8a278ce..5d83c7b 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,2660 @@ +2009-09-24 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + Reviewed by Simon Hausmann. + + Fix QApp::translate() calls to provide the correct class name without + a trailing comma. + + * platform/qt/Localizations.cpp: + (WebCore::localizedMediaTimeDescription): + +2009-09-24 Geoffrey Garen <ggaren@apple.com> + + More build fix: Removed JSSharedWorkerContextCustom.cpp from project + files, since it no longer exists in the repository. + + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + +2009-09-24 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Declare set/unsetPendingActivity public, so + SharedWorkerScriptLoader can call them. + + * dom/ActiveDOMObject.h: + +2009-09-24 Geoffrey Garen <ggaren@apple.com> + + Fixed a bit of the Windows build. + + * workers/SharedWorker.idl: Declare a custom mark function. (I accidentally + removed this in my last patch.) + * WebCore.xcodeproj/project.pbxproj: Added JSSharedWorkerCustom.cpp back + to the build. (I accidentally removed this in my last patch.) + +2009-09-23 Geoffrey Garen <ggaren@apple.com> + + 32-bit build fix: restore previous cast that I thought was unnecessary. + + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::didSendData): + (WebCore::XMLHttpRequest::didReceiveData): + +2009-09-23 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Bring a little sanity to this crazy EventTarget world of ours + https://bugs.webkit.org/show_bug.cgi?id=29701 + + Lots of EventTarget refactoring to achieve a single shared implementation + that fixes some of the performance and correctness bugs of the many individual + implementations, and makes reasoning about EventTargets and EventListeners + much easier. + + The basic design is this: + - EventTarget manages a set of EventListeners. + - onXXX EventListener attributes forward to standard EventTarget APIs. + - Since the onXXX code is repetitive, it is usually done with macros + of the form DEFINE_ATTRIBUTE_EVENT_LISTENER(attributeName). + - EventTarget provides a shared implementation of dispatchEvent, + which subclasses with special event dispatch rules, like Node, override. + - To support Node, which lazily instantiates its EventTarget data, + EventTarget has no data members, and instead makes a virtual call + to get its data from wherever its subclass chose to store it. + + Code that used to call dispatchEvent, passing an ExceptionCode paratmeter, + even though no exception could be thrown, has been changed not to do so, + to improve clarity and performance. + + Code that used to call a special dispatchXXXEvent function, which just + turned around and called dispatchEvent, has been changed to call + dispatchEvent, to improve clarity and performance. + + * WebCore.base.exp: + * WebCore.xcodeproj/project.pbxproj: Another day in the life of a WebKit + engineer. + + * bindings/js/JSDOMBinding.cpp: + (WebCore::isObservableThroughDOM): Updated for Node API change. Added + "is not in the document but is firing event listeners" as a condition + that makes a Node observable in the DOM, so that event listeners firing + on removed nodes are not destroyed midstream. (This was a long-standing + bug that was somewhat hidden by the old implementation's habit of + copying the RegisteredEventListener vector before firing events, which + would keep almost all the relevant objects from being destroyed.) + + * bindings/js/JSEventListener.cpp: + (WebCore::JSEventListener::handleEvent): Removed the isWindowEvent flag + because it was one of the most elaborately planned no-ops in the history + of software crime, and one of the reasons clients thought they needed more + than one dispatchEvent function even though they didn't. + * bindings/js/JSEventListener.h: + + * bindings/js/JSDOMWindowCustom.cpp: + (WebCore::JSDOMWindow::markChildren): + (WebCore::JSMessagePort::markChildren): + * bindings/js/JSNodeCustom.cpp: + (WebCore::JSNode::markChildren): + * bindings/js/JSAbstractWorkerCustom.cpp: + * bindings/js/JSDOMApplicationCacheCustom.cpp: + * bindings/js/JSDedicatedWorkerContextCustom.cpp: + * bindings/js/JSEventSourceCustom.cpp: + * bindings/js/JSMessagePortCustom.cpp: + * bindings/js/JSSharedWorkerContextCustom.cpp: Removed. + * bindings/js/JSWebSocketCustom.cpp: + * bindings/js/JSWorkerContextCustom.cpp: + (WebCore::JSWorkerContext::markChildren): + * bindings/js/JSWorkerCustom.cpp: + * bindings/js/JSXMLHttpRequestCustom.cpp: + (WebCore::JSXMLHttpRequest::markChildren): + * bindings/js/JSXMLHttpRequestUploadCustom.cpp: + (WebCore::JSXMLHttpRequestUpload::markChildren): EventListener marking is + now autogenerated. Classes that still have custom mark functions for other + reasons now call a shared EventTarget API to mark their EventListeners. + + * bindings/objc/ObjCEventListener.h: + * bindings/objc/ObjCEventListener.mm: + (WebCore::ObjCEventListener::handleEvent): Bye bye isWindowEvent. + + * bindings/scripts/CodeGeneratorJS.pm: Autogeneration support for + marking and invalidating event listeners. + + * dom/CharacterData.cpp: + (WebCore::CharacterData::dispatchModifiedEvent): + * dom/ContainerNode.cpp: + (WebCore::ContainerNode::insertBefore): + (WebCore::ContainerNode::replaceChild): + (WebCore::willRemoveChild): + (WebCore::ContainerNode::appendChild): + (WebCore::dispatchChildInsertionEvents): + (WebCore::dispatchChildRemovalEvents): + * dom/Document.cpp: + (WebCore::Document::removeAllEventListeners): + (WebCore::Document::implicitClose): + (WebCore::Document::setFocusedNode): + (WebCore::Document::dispatchWindowEvent): + (WebCore::Document::dispatchWindowLoadEvent): + (WebCore::Document::finishedParsing): + * dom/Document.h: Use dispatchEvent directly. + + * dom/Element.h: Moved a few event listener attributes down from Node, + since they don't apply to all Nodes, only Elements. + + * dom/EventListener.h: Removed isWindowEvent parameter. + + * dom/EventNames.h: Added the "display" event name, so it works correctly + with attribute macros, and for performance. + + * dom/EventTarget.cpp: + (WebCore::forbidEventDispatch): + (WebCore::allowEventDispatch): + (WebCore::eventDispatchForbidden): Made this code (embarrasingly) thread + safe, since it's now called on multiple threads. (Currently, we only forbid + event dispatch on the main thread. If we ever want to forbid event dispatch + on secondary threads, we can improve it then.) + + (WebCore::EventTarget::addEventListener): + (WebCore::EventTarget::removeEventListener): + (WebCore::EventTarget::setAttributeEventListener): + (WebCore::EventTarget::getAttributeEventListener): + (WebCore::EventTarget::clearAttributeEventListener): + (WebCore::EventTarget::dispatchEvent): + (WebCore::EventTarget::fireEventListeners): + (WebCore::EventTarget::getEventListeners): + (WebCore::EventTarget::removeAllEventListeners): + * dom/EventTarget.h: + (WebCore::FiringEventEndIterator::FiringEventEndIterator): + (WebCore::EventTarget::ref): + (WebCore::EventTarget::deref): + (WebCore::EventTarget::markEventListeners): + (WebCore::EventTarget::invalidateEventListeners): + (WebCore::EventTarget::isFiringEventListeners): + (WebCore::EventTarget::hasEventListeners): The ONE TRUE IMPLEMENTATION of + EventTarget APIs, crafted from an amalgam of all the different versions + we used to have. The most significant change here is that we no longer + make a copy of an EventListener vector before firing the events in the + vector -- instead, we use a reference to the original vector, along with + a notification mechanism for the unlikely case when an EventListener is + removed from the vector. This substantially reduces malloc, copying, and + refcount overhead, and complexity. + + * dom/InputElement.cpp: + (WebCore::InputElement::setValueFromRenderer): + * dom/MessageEvent.h: + (WebCore::MessageEvent::create): Use dispatchEvent directly. + + * dom/MessagePort.cpp: + (WebCore::MessagePort::dispatchMessages): + (WebCore::MessagePort::eventTargetData): + (WebCore::MessagePort::ensureEventTargetData): + * dom/MessagePort.h: + (WebCore::MessagePort::setOnmessage): + (WebCore::MessagePort::onmessage): + * dom/MessagePort.idl: Removed custom EventTarget implementation. + + * dom/MutationEvent.h: + (WebCore::MutationEvent::create): Added some default values so callers + can construct MutationEvents more easily, without calling a custom dispatch + function. + + * dom/Node.cpp: + (WebCore::Node::addEventListener): + (WebCore::Node::removeEventListener): + (WebCore::Node::eventTargetData): + (WebCore::Node::ensureEventTargetData): + (WebCore::Node::handleLocalEvents): + (WebCore::Node::dispatchEvent): + (WebCore::Node::dispatchGenericEvent): + (WebCore::Node::dispatchSubtreeModifiedEvent): + (WebCore::Node::dispatchUIEvent): + (WebCore::Node::dispatchKeyEvent): + (WebCore::Node::dispatchMouseEvent): + (WebCore::Node::dispatchWheelEvent): + (WebCore::Node::dispatchFocusEvent): + (WebCore::Node::dispatchBlurEvent): + * dom/Node.h: + (WebCore::Node::preDispatchEventHandler): + (WebCore::Node::postDispatchEventHandler): + * dom/Node.idl: + * dom/NodeRareData.h: + (WebCore::NodeRareData::eventTargetData): + (WebCore::NodeRareData::ensureEventTargetData): Use the shared EventTarget + interface, and call dispatchEvent directly instead of custom dispatchXXXEvent + functions that just forwarded to dispatchEvent. + + * dom/RegisteredEventListener.cpp: + * dom/RegisteredEventListener.h: + (WebCore::RegisteredEventListener::RegisteredEventListener): + (WebCore::operator==): This is just a simple struct now, since we no longer + do a complicated copy / refCount / isRemoved dance just to honor the rule + that an EventListener can be removed during event dispatch. + + * history/CachedFrame.cpp: + (WebCore::CachedFrameBase::restore): Removed another custom dispatchEvent. + + * html/HTMLBodyElement.cpp: + * html/HTMLBodyElement.h: Use the shared EventTarget API. + + * html/HTMLFormControlElement.cpp: + (WebCore::HTMLFormControlElement::dispatchFormControlChangeEvent): + (WebCore::HTMLFormControlElement::checkValidity): + * html/HTMLFormElement.cpp: + (WebCore::HTMLFormElement::handleLocalEvents): + (WebCore::HTMLFormElement::prepareSubmit): + (WebCore::HTMLFormElement::reset): + * html/HTMLFormElement.h: Use the standard dispatchEvent API. + + * html/HTMLFrameSetElement.cpp: + * html/HTMLFrameSetElement.h: Use the shared EventTarget API. + + * html/HTMLImageLoader.cpp: + (WebCore::HTMLImageLoader::dispatchLoadEvent): + * html/HTMLInputElement.cpp: + (WebCore::HTMLInputElement::onSearch): + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::loadInternal): + * html/HTMLScriptElement.cpp: + (WebCore::HTMLScriptElement::dispatchLoadEvent): + (WebCore::HTMLScriptElement::dispatchErrorEvent): + * html/HTMLSourceElement.cpp: + (WebCore::HTMLSourceElement::errorEventTimerFired): + * html/HTMLTokenizer.cpp: + (WebCore::HTMLTokenizer::notifyFinished): Use the standard dispatchEvent API. + + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::handleEvent): + * inspector/InspectorDOMAgent.h: + * inspector/InspectorDOMStorageResource.cpp: + (WebCore::InspectorDOMStorageResource::handleEvent): + * inspector/InspectorDOMStorageResource.h: + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::stopLoading): + (WebCore::FrameLoader::canCachePageContainingThisFrame): + (WebCore::FrameLoader::logCanCacheFrameDecision): + (WebCore::HashChangeEventTask::performTask): + (WebCore::FrameLoader::pageHidden): No more isWindowEvent. + + * loader/ImageDocument.cpp: + (WebCore::ImageEventListener::handleEvent): + * loader/appcache/ApplicationCacheGroup.cpp: + (WebCore::CallCacheListenerTask::performTask): + * loader/appcache/ApplicationCacheHost.cpp: + (WebCore::ApplicationCacheHost::notifyDOMApplicationCache): + * loader/appcache/ApplicationCacheHost.h: + * loader/appcache/DOMApplicationCache.cpp: + (WebCore::DOMApplicationCache::eventTargetData): + (WebCore::DOMApplicationCache::ensureEventTargetData): + * loader/appcache/DOMApplicationCache.h: + * loader/appcache/DOMApplicationCache.idl: Switched to the standard + EventTarget API. As a part of this, I switched this class from using a + custom internal event name enumeration to using the standard EventNames. + + * notifications/Notification.cpp: + (WebCore::Notification::eventTargetData): + (WebCore::Notification::ensureEventTargetData): + * notifications/Notification.h: + (WebCore::Notification::scriptExecutionContext): + * notifications/Notification.idl: Switched to the standard EventTarget API. + + * page/DOMWindow.cpp: + (WebCore::PostMessageTimer::event): + (WebCore::windowsWithUnloadEventListeners): + (WebCore::windowsWithBeforeUnloadEventListeners): + (WebCore::allowsBeforeUnloadListeners): + (WebCore::DOMWindow::dispatchAllPendingBeforeUnloadEvents): + (WebCore::DOMWindow::pendingUnloadEventListeners): + (WebCore::DOMWindow::dispatchAllPendingUnloadEvents): Changed the "pending" + unload / beforeunload listener tracker just to track which windows had + such listeners, instead of actually keeping a copy of the listeners. Now, + this code can use the standard EventTarget API. + + (WebCore::DOMWindow::~DOMWindow): + (WebCore::DOMWindow::postMessageTimerFired): + (WebCore::DOMWindow::addEventListener): + (WebCore::DOMWindow::removeEventListener): + (WebCore::DOMWindow::dispatchLoadEvent): + (WebCore::DOMWindow::dispatchEvent): + (WebCore::DOMWindow::removeAllEventListeners): + (WebCore::DOMWindow::captureEvents): + (WebCore::DOMWindow::releaseEvents): + (WebCore::DOMWindow::eventTargetData): + (WebCore::DOMWindow::ensureEventTargetData): + * page/DOMWindow.h: + * page/DOMWindow.idl: Use the standard EventTarget APIs. + + * page/EventHandler.cpp: + (WebCore::EventHandler::canMouseDownStartSelect): + (WebCore::EventHandler::canMouseDragExtendSelect): + (WebCore::EventHandler::sendResizeEvent): + (WebCore::EventHandler::sendScrollEvent): Use dispatchEvent directly. + + * page/EventSource.cpp: + (WebCore::EventSource::endRequest): + (WebCore::EventSource::didReceiveResponse): + (WebCore::EventSource::parseEventStreamLine): + (WebCore::EventSource::stop): + (WebCore::EventSource::createMessageEvent): + (WebCore::EventSource::eventTargetData): + (WebCore::EventSource::ensureEventTargetData): + * page/EventSource.h: + * page/EventSource.idl: Use the standard EventTarget APIs. + + * page/FocusController.cpp: + (WebCore::dispatchEventsOnWindowAndFocusedNode): + (WebCore::FocusController::setFocusedFrame): + * page/Frame.cpp: + (WebCore::Frame::shouldClose): + * page/Frame.h: + * page/Page.cpp: + (WebCore::networkStateChanged): + * page/animation/AnimationController.cpp: + (WebCore::AnimationControllerPrivate::updateStyleIfNeededDispatcherFired): + * rendering/RenderListBox.cpp: + (WebCore::RenderListBox::valueChanged): + * rendering/RenderTextControl.cpp: + (WebCore::RenderTextControl::selectionChanged): + * rendering/RenderTextControlMultiLine.cpp: + (WebCore::RenderTextControlMultiLine::subtreeHasChanged): Use dispatchEvent. + + * svg/SVGElement.cpp: + (WebCore::hasLoadListener): Rewritten for new EventTarget API. + + * svg/SVGElementInstance.cpp: + (WebCore::dummyEventTargetData): + (WebCore::SVGElementInstance::addEventListener): + (WebCore::SVGElementInstance::removeEventListener): + (WebCore::SVGElementInstance::removeAllEventListeners): + (WebCore::SVGElementInstance::dispatchEvent): + (WebCore::SVGElementInstance::eventTargetData): + (WebCore::SVGElementInstance::ensureEventTargetData): Use the EventTarget API. + + * svg/SVGElementInstance.h: + * svg/SVGImageLoader.cpp: + (WebCore::SVGImageLoader::dispatchLoadEvent): + * svg/SVGScriptElement.cpp: + (WebCore::SVGScriptElement::dispatchErrorEvent): Use dispatchEvent directly. + + * svg/SVGUseElement.cpp: + (WebCore::SVGUseElement::transferEventListenersToShadowTree): Updated for + new EventTarget API. + + * svg/animation/SVGSMILElement.cpp: + (WebCore::ConditionEventListener::handleEvent): No more isWindowEvent. + + * websockets/WebSocket.cpp: + (WebCore::ProcessWebSocketEventTask::create): + (WebCore::ProcessWebSocketEventTask::performTask): + (WebCore::ProcessWebSocketEventTask::ProcessWebSocketEventTask): + (WebCore::WebSocket::didConnect): + (WebCore::WebSocket::didReceiveMessage): + (WebCore::WebSocket::didClose): + (WebCore::WebSocket::eventTargetData): + (WebCore::WebSocket::ensureEventTargetData): + * websockets/WebSocket.h: + * websockets/WebSocket.idl: + * workers/AbstractWorker.cpp: + (WebCore::AbstractWorker::eventTargetData): + (WebCore::AbstractWorker::ensureEventTargetData): + * workers/AbstractWorker.h: + * workers/AbstractWorker.idl: + * workers/DedicatedWorkerContext.cpp: + * workers/DedicatedWorkerContext.h: + * workers/DedicatedWorkerContext.idl: + * workers/DefaultSharedWorkerRepository.cpp: + (WebCore::SharedWorkerConnectTask::performTask): + (WebCore::SharedWorkerScriptLoader::load): + (WebCore::SharedWorkerScriptLoader::notifyFinished): + * workers/SharedWorker.idl: + * workers/SharedWorkerContext.cpp: + (WebCore::createConnectEvent): + * workers/SharedWorkerContext.h: + * workers/SharedWorkerContext.idl: + * workers/Worker.cpp: + (WebCore::Worker::notifyFinished): + * workers/Worker.h: + * workers/Worker.idl: + * workers/WorkerContext.cpp: + (WebCore::WorkerContext::eventTargetData): + (WebCore::WorkerContext::ensureEventTargetData): + * workers/WorkerContext.h: + * workers/WorkerContext.idl: + * workers/WorkerMessagingProxy.cpp: + (WebCore::MessageWorkerContextTask::performTask): + (WebCore::MessageWorkerTask::performTask): + (WebCore::WorkerExceptionTask::performTask): + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::callReadyStateChangeListener): + (WebCore::XMLHttpRequest::createRequest): + (WebCore::XMLHttpRequest::abort): + (WebCore::XMLHttpRequest::networkError): + (WebCore::XMLHttpRequest::abortError): + (WebCore::XMLHttpRequest::didSendData): + (WebCore::XMLHttpRequest::didReceiveData): + (WebCore::XMLHttpRequest::eventTargetData): + (WebCore::XMLHttpRequest::ensureEventTargetData): + * xml/XMLHttpRequest.h: + * xml/XMLHttpRequest.idl: + * xml/XMLHttpRequestProgressEvent.h: + (WebCore::XMLHttpRequestProgressEvent::create): + * xml/XMLHttpRequestUpload.cpp: + (WebCore::XMLHttpRequestUpload::eventTargetData): + (WebCore::XMLHttpRequestUpload::ensureEventTargetData): + * xml/XMLHttpRequestUpload.h: + * xml/XMLHttpRequestUpload.idl: Use new EventTarget API. + +2009-09-23 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Adler. + + - Support for maxLength of <textarea> + - Move numGraphemeClusters() and numCharactersInGraphemeClusters() from InputElement to String. + https://bugs.webkit.org/show_bug.cgi?id=29292 + + Test: fast/forms/textarea-maxlength.html + + * dom/InputElement.cpp: + (WebCore::InputElement::sanitizeUserInputValue): + (WebCore::InputElement::handleBeforeTextInsertedEvent): + * html/HTMLTextAreaElement.cpp: + (WebCore::HTMLTextAreaElement::defaultEventHandler): + (WebCore::HTMLTextAreaElement::handleBeforeTextInsertedEvent): + (WebCore::HTMLTextAreaElement::sanitizeUserInputValue): + (WebCore::HTMLTextAreaElement::maxLength): + (WebCore::HTMLTextAreaElement::setMaxLength): + * html/HTMLTextAreaElement.h: + * html/HTMLTextAreaElement.idl: + * platform/text/PlatformString.h: + * platform/text/String.cpp: + (WebCore::String::numGraphemeClusters): + (WebCore::String::numCharactersInGraphemeClusters): + +2009-09-23 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Xan Lopez. + + [GTK] REGRESSION: BitmapImage::getGdkPixbuf fails for non-square images + https://bugs.webkit.org/show_bug.cgi?id=29654 + + Give GDK_Backspace key events the proper text properties. + + Instead of adding new tests, this change removes existing tests + from Gtk's skipped list. + + * platform/gtk/KeyEventGtk.cpp: + (WebCore::keyIdentifierForGdkKeyCode): + (WebCore::singleCharacterString): + +2009-09-23 Sam Weinig <sam@webkit.org> + + Reviewed by Adam Barth. + + Fix for https://bugs.webkit.org/show_bug.cgi?id=26989 + Should allow navigation of top-level openers + <rdar://problem/7034025> + + Allow navigation of cross-origin window.opener if it is top-level frame. + + Test: http/tests/security/frameNavigation/cross-origin-opener.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::shouldAllowNavigation): + +2009-09-23 Marshall Culpepper <mculpepper@appcelerator.com> + + Reviewed by Eric Seidel. + + Added $(WebKitLibrariesDir)/include/cairo so cairo.h is found by + default when the necessary dependencies are extracted into the + WebKitLibrariesDir. + https://bugs.webkit.org/show_bug.cgi?id=29661 + + * WebCore.vcproj/WebCoreCairo.vsprops: + +2009-09-23 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Crash when website does a history.back() followed by an alert() + https://bugs.webkit.org/show_bug.cgi?id=29686 + rdar://problem/6984996 + + When loading is deferred, we need to defer timer-based loads + too, not just networking-driven loads. Otherwise we can get + syncronouse navigation while running a script, which leads to + crashes and other badness. + + This patch includes a manual test; an automated test may be + possible some time in the future. + + * dom/Document.cpp: + (WebCore::Document::processHttpEquiv): Use scheduleLocationChange + instead of scheduleHTTPRedirection to implement the navigation + needed for x-frame-options. + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::FrameLoader): Updated for data members with + new names and new data members. + (WebCore::FrameLoader::setDefersLoading): When turning deferral + off, call startRedirectionTimer and startCheckCompleteTimer, since + either of them might have been fired and ignored while defersLoading + was true. + (WebCore::FrameLoader::clear): Updated for replacement of the + m_checkCompletedTimer and m_checkLoadCompleteTimer timers. + (WebCore::FrameLoader::allAncestorsAreComplete): Added. + (WebCore::FrameLoader::checkCompleted): Added code to set + m_shouldCallCheckCompleted to false. Changed code that calls + startRedirectionTimer to call it unconditionally, since that + function now knows when to do work and doesn't expect callers + to handle that any more. + (WebCore::FrameLoader::checkTimerFired): Added. Replaces the old + timer fired callbacks. Calls checkCompleted and checkLoadComplete + as appropriate, but not when defersLoading is true. + (WebCore::FrameLoader::startCheckCompleteTimer): Added. Replaces + the two different calls to start timers before. Only starts the + timers if they are needed. + (WebCore::FrameLoader::scheduleCheckCompleted): Changed to call + startCheckCompleteTimer after setting boolean. + (WebCore::FrameLoader::scheduleCheckLoadComplete): Ditto. + (WebCore::FrameLoader::scheduleHistoryNavigation): Removed + canGoBackOrForward check. The logic works more naturally when + we don't do anything until the timer fires. + (WebCore::FrameLoader::redirectionTimerFired): Do nothing if + defersLoading is true. Also moved canGoBackOrForward check here. + (WebCore::FrameLoader::scheduleRedirection): Changed code that + calls startRedirectionTimer to do so unconditionally. That + function now handles the rules about when to start the timer + rather than expecting the caller to do so. + (WebCore::FrameLoader::startRedirectionTimer): Added code to + handle the case where there is no redirection scheduled, + where the timer is already active, or where this is a classic + redirection and there is an ancestor that has not yet completed + loading. + (WebCore::FrameLoader::completed): Call startRedirectionTimer + here directly instead of calling a cover named parentCompleted. + Hooray! One less function in the giant FrameLoader class! + (WebCore::FrameLoader::checkLoadComplete): Added code to set + m_shouldCallCheckLoadComplete to false. + + * loader/FrameLoader.h: Replaced the two functions + checkCompletedTimerFired and checkLoadCompleteTimerFired with + one function, checkTimerFired. Removed the parentCompleted + function. Added the startCheckCompleteTimer and + allAncestorsAreComplete functions. Replaced the + m_checkCompletedTimer and m_checkLoadCompleteTimer data + members with m_checkTimer, m_shouldCallCheckCompleted, and + m_shouldCallCheckLoadComplete. + + * manual-tests/go-back-after-alert.html: Added. + * manual-tests/resources/alert-and-go-back.html: Added. + +2009-09-23 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29660> Move "Generate 64-bit Export File" build phase script into DerivedSources.make + + Reviewed by Mark Rowe. + + The "Generate 64-bit Export File" build phase script generated + the WebCore.LP64.exp export file used to link 64-bit WebCore. + Instead of having a separate build phase script, move its + generation into DerivedSources.make where WebCore.exp is + generated. + + * DerivedSources.make: Added a rule to make WebCore.LP64.exp. + Added code to append WebCore.PluginHostProcess.exp to + $(WEBCORE_EXPORT_DEPENDENCIES) when WTF_USE_PLUGIN_HOST_PROCESS + is set to 1. + * WebCore.PluginHostProcess.exp: Renamed from WebCore/WebCore.LP64.exp. + * WebCore.xcodeproj/project.pbxproj: Removed the "Generate + 64-bit Export File" build phase script. Renamed WebCore.LP64.exp + to WebCore.PluginHostProcess.exp. + +2009-09-23 Peter Kasting <pkasting@google.com> + + Reviewed by Dimitri Glazkov. + + https://bugs.webkit.org/show_bug.cgi?id=29694 + [Chromium] Eliminate dependency on gfx::Rect from ImageSkia. + + * platform/graphics/skia/ImageSkia.cpp: + (WebCore::drawResampledBitmap): + +2009-09-22 Timothy Hatcher <timothy@apple.com> + + Prevent scrolling multiple elements during latched wheel events. + + Reviewed by Anders Carlsson. + + * page/EventHandler.cpp: + (WebCore::scrollAndAcceptEvent): + (WebCore::EventHandler::clear): + (WebCore::EventHandler::handleWheelEvent): + * page/EventHandler.h: + * rendering/RenderBox.cpp: + (WebCore::RenderBox::scroll): + * rendering/RenderBox.h: + +2009-09-23 Daniel Bates <dbates@webkit.org> + + Reviewed by Adam Barth. + + https://bugs.webkit.org/show_bug.cgi?id=29523 + + Fixes an issue where a JavaScript URL that was URL-encoded twice can bypass the + XSSAuditor. + + The method FrameLoader::executeIfJavaScriptURL decodes the URL escape + sequences in a JavaScript URL before it is eventually passed to the XSSAuditor. + Because the XSSAuditor also decodes the URL escape sequences as part of its + canonicalization, the double decoding of a JavaScript URL would + not match the canonicalization of the input parameters. + + Tests: http/tests/security/xssAuditor/iframe-javascript-url-url-encoded.html + http/tests/security/xssAuditor/javascript-link-url-encoded.html + + * bindings/js/ScriptController.cpp: + (WebCore::ScriptController::evaluate): Moved call to + XSSAuditor::canEvaluateJavaScriptURL into FrameLoader::executeIfJavaScriptURL. + * bindings/v8/ScriptController.cpp: + (WebCore::ScriptController::evaluate): Ditto. + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::executeIfJavaScriptURL): Modified to call + XSSAuditor::canEvaluateJavaScriptURL on the JavaScript URL before it is + decoded. + +2009-09-22 Dave Hyatt <hyatt@apple.com> + + Reviewed by John Sullivan. + + https://bugs.webkit.org/show_bug.cgi?id=29657 + Columns don't break properly in positioned elements with a fixed height. Make sure that + a block is still considered to have columns even when the column count is 1 if the column + width is non-auto. + + Added fast/multicol/positioned-with-constrained-height.html + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::setDesiredColumnCountAndWidth): + +2009-09-23 Holger Hans Peter Freyther <zecke@selfish.org> + + Rubber-stamped by Simon Hausmann. + + Add a null check for the Document*. In the mirror benchmarking + application a crash from a call from JavaScript was observed. + + I was not able to come up with a test case for this issue. + + * platform/qt/CookieJarQt.cpp: + (WebCore::cookieJar): + +2009-09-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Fix the Qt/Windows build, after the introduction of + the page client. + + * plugins/win/PluginViewWin.cpp: + (windowHandleForPageClient): + (WebCore::PluginView::getValue): + (WebCore::PluginView::forceRedraw): + (WebCore::PluginView::platformStart): + +2009-09-23 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Xan Lopez. + + [GTK] media tests failing after their rework + https://bugs.webkit.org/show_bug.cgi?id=29532 + + Correctly advertise the mime types used by the common formats used + in the tests. + + Tests that regressed, and will pass again: + + media/video-canvas-source.html + media/video-controls.html + media/video-currentTime-set2.html + media/video-dom-autoplay.html + media/video-dom-src.html + media/video-error-abort.html + media/video-load-networkState.html + media/video-load-readyState.html + media/video-muted.html + media/video-no-autoplay.html + media/video-pause-empty-events.html + media/video-play-empty-events.html + media/video-seekable.html + media/video-seeking.html + media/video-size.html + media/video-source-type-params.html + media/video-source-type.html + media/video-source.html + media/video-src-change.html + media/video-src-invalid-remove.html + media/video-src-remove.html + media/video-src-set.html + media/video-src-source.html + media/video-src.html + media/video-timeupdate-during-playback.html + media/video-volume.html + + * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: + (WebCore::mimeTypeCache): + +2009-09-22 Charles Wei <charles.wei@torchmobile.com.cn> + + Reviewed by Eric Seidel. + + Fix the crash problem with absolte positioned children in foreignobject + htts://bugs.webkit.org/show_bug.cgi?id=26342 + + Test: svg/custom/foreignobject-crash-with-absolute-positioned-children.svg + + * rendering/RenderForeignObject.h: + (WebCore::RenderForeignObject::isSVGForeignObject): + * rendering/RenderObject.cpp: + (WebCore::RenderObject::containingBlock): + * rendering/RenderObject.h: + (WebCore::RenderObject::isSVGForeignObject): + +2009-09-22 Drew Wilson <atwilson@google.com> + + Reviewed by David Levin. + + SharedWorkers "name" attribute is now optional. + https://bugs.webkit.org/show_bug.cgi?id=28897 + + Test: fast/workers/shared-worker-name.html + + * bindings/js/JSSharedWorkerConstructor.cpp: + (WebCore::constructSharedWorker): + Default 'name' attribute to empty string if it is not provided. + * bindings/v8/custom/V8SharedWorkerCustom.cpp: + (WebCore::CALLBACK_FUNC_DECL): + Default 'name' attribute to empty string if it is not provided. + * workers/DefaultSharedWorkerRepository.cpp: + (WebCore::SharedWorkerProxy::matches): + Now matches URLs if names are empty strings. + (WebCore::DefaultSharedWorkerRepository::getProxy): + Pass URL in to SharedWorkerProxy::matches(). + +2009-09-22 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed, another build fix. + + [Chromium] Add another missing include. + https://bugs.webkit.org/show_bug.cgi?id=29536 + + * inspector/InspectorController.cpp: Added DOMWindow.h include. + +2009-09-22 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed, build fix. + + [Chromium] Add missing include. + https://bugs.webkit.org/show_bug.cgi?id=29536 + + * inspector/InspectorDOMStorageResource.cpp: Added DOMWindow.h include. + +2009-09-22 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Tighten up the ScheduledRedirection machinery to prepare for a bug fix + https://bugs.webkit.org/show_bug.cgi?id=29663 + + * loader/FrameLoader.cpp: + (WebCore::ScheduledRedirection::ScheduledRedirection): Added a boolean, + initialized to false, to keep track if the redirection has been + communicated to the client. + (WebCore::FrameLoader::stopLoading): Tweaked a comment. + (WebCore::FrameLoader::cancelRedirection): Removed code to clear + m_scheduledRedirection.clear since stopRedirectionTimer does that now. + (WebCore::FrameLoader::allChildrenAreComplete): Added. + (WebCore::FrameLoader::checkCompleted): Use allChildrenAreComplete + function for clarity. + (WebCore::FrameLoader::checkCallImplicitClose): Ditto. + (WebCore::FrameLoader::scheduleRedirection): Changed to take a PassOwnPtr. + (WebCore::FrameLoader::startRedirectionTimer): Added code to set the + toldClient flag and not call clientRedirected a second time if it is set. + (WebCore::FrameLoader::stopRedirectionTimer): Changed so this can be safely + called multiple times and it will call clientRedirectCancelledOrFinished + only once. + + * loader/FrameLoader.h: Changed scheduleRedirection to be a PassOwnPtr. + Added allChildrenAreComplete function. + +2009-09-22 Yury Semikhatsky <yurys@chromium.org> + + Reviewed by Timothy Hatcher. + + WebInspector: Migrate Databases tab to InjectedScript / + serialized interaction. + + DOMStorage interaction is now serialized into JSON messages + and doesn't require quarantined objects. + + https://bugs.webkit.org/show_bug.cgi?id=28873 + + * dom/EventListener.h: + (WebCore::EventListener::): + * inspector/InspectorBackend.cpp: + (WebCore::InspectorBackend::selectDOMStorage): + (WebCore::InspectorBackend::getDOMStorageEntries): + (WebCore::InspectorBackend::setDOMStorageItem): + (WebCore::InspectorBackend::removeDOMStorageItem): + * inspector/InspectorBackend.h: + * inspector/InspectorBackend.idl: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::didCommitLoad): + (WebCore::InspectorController::selectDOMStorage): + (WebCore::InspectorController::getDOMStorageEntries): + (WebCore::InspectorController::setDOMStorageItem): + (WebCore::InspectorController::removeDOMStorageItem): + (WebCore::InspectorController::getDOMStorageResourceForId): + * inspector/InspectorController.h: + * inspector/InspectorDOMStorageResource.cpp: + (WebCore::InspectorDOMStorageResource::InspectorDOMStorageResource): + (WebCore::InspectorDOMStorageResource::bind): + (WebCore::InspectorDOMStorageResource::unbind): + (WebCore::InspectorDOMStorageResource::startReportingChangesToFrontend): + (WebCore::InspectorDOMStorageResource::handleEvent): + (WebCore::InspectorDOMStorageResource::operator==): + * inspector/InspectorDOMStorageResource.h: + (WebCore::InspectorDOMStorageResource::cast): + (WebCore::InspectorDOMStorageResource::id): + (WebCore::InspectorDOMStorageResource::domStorage): + * inspector/InspectorFrontend.cpp: + (WebCore::InspectorFrontend::selectDOMStorage): + (WebCore::InspectorFrontend::didGetDOMStorageEntries): + (WebCore::InspectorFrontend::didSetDOMStorageItem): + (WebCore::InspectorFrontend::didRemoveDOMStorageItem): + (WebCore::InspectorFrontend::updateDOMStorage): + * inspector/InspectorFrontend.h: + * inspector/front-end/DOMStorage.js: + (WebInspector.DOMStorage): + (WebInspector.DOMStorage.prototype.get id): + (WebInspector.DOMStorage.prototype.get domStorage): + (WebInspector.DOMStorage.prototype.get isLocalStorage): + (WebInspector.DOMStorage.prototype.getEntriesAsync): + (WebInspector.DOMStorage.prototype.setItemAsync): + (WebInspector.DOMStorage.prototype.removeItemAsync): + * inspector/front-end/DOMStorageDataGrid.js: + (WebInspector.DOMStorageDataGrid): + (WebInspector.DOMStorageDataGrid.prototype._startEditingColumnOfDataGridNode): + (WebInspector.DOMStorageDataGrid.prototype._startEditing): + (WebInspector.DOMStorageDataGrid.prototype._editingCommitted): + (WebInspector.DOMStorageDataGrid.prototype._editingCancelled): + (WebInspector.DOMStorageDataGrid.prototype.deleteSelectedRow): + * inspector/front-end/DOMStorageItemsView.js: + (WebInspector.DOMStorageItemsView.prototype.update): + (WebInspector.DOMStorageItemsView.prototype._showDOMStorageEntries): + (WebInspector.DOMStorageItemsView.prototype._dataGridForDOMStorageEntries): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel.prototype.show): + (WebInspector.StoragePanel.prototype.reset): + (WebInspector.StoragePanel.prototype.selectDOMStorage): + (WebInspector.StoragePanel.prototype.updateDOMStorage): + (WebInspector.StoragePanel.prototype._domStorageForId): + * inspector/front-end/inspector.js: + (WebInspector.addDOMStorage): + (WebInspector.updateDOMStorage): + +2009-09-22 Sam Weinig <sam@webkit.org> + + Reviewed by Alexey Proskuryakov. + + Fix for XMLHttpRequest.abort() should destroy the response text. + https://bugs.webkit.org/show_bug.cgi?id=29658 + <rdar://problem/5301430> + + Clearing the response text after calling XMLHttpRequest.abort() is necessary + per spec and matches Firefox. It is also a potential memory win. + + Test: http/tests/xmlhttprequest/abort-should-destroy-responseText.html + + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::abort): Clear the response text making sure to + keep the actual ResourceReponse around so that the response status and response + status text are kept around. + +2009-09-22 Dimitri Glazkov <dglazkov@chromium.org> + + No review, rolling out r48639. + http://trac.webkit.org/changeset/48639 + + * bindings/v8/V8GCController.cpp: + (WebCore::ObjectGrouperVisitor::visitDOMWrapper): + +2009-09-22 Dumitru Daniliuc <dumi@chromium.org> + + Reviewed by Dimitri Glazkov. + + Changing the transaction coordinator to (re-)allow multiple read + transactions on the same database to run concurrently (without + risking a deadlock this time). + + https://bugs.webkit.org/show_bug.cgi?id=29115 + + Tests: storage/read-and-write-transactions-dont-run-together.html + storage/read-transactions-running-concurrently.html + + * storage/SQLTransaction.h: + (WebCore::SQLTransaction::isReadOnly): Returns the type of the + transaction. + * storage/SQLTransactionCoordinator.cpp: + (WebCore::SQLTransactionCoordinator::acquireLock): Changed to + allow multiple read transactions on the same DB to run + concurrently. + (WebCore::SQLTransactionCoordinator::releaseLock): Changed to + allow multiple read transactions on the same DB to run + concurrently. + (WebCore::SQLTransactionCoordinator::shutdown): Renamed the map. + * storage/SQLTransactionCoordinator.h: + +2009-09-22 Peter Kasting <pkasting@google.com> + + Reviewed by David Levin. + + https://bugs.webkit.org/show_bug.cgi?id=29652 + Support true system colors for CSS system colors in Chromium/Win. + + * rendering/RenderThemeChromiumWin.cpp: + (WebCore::cssValueIdToSysColorIndex): + (WebCore::RenderThemeChromiumWin::systemColor): + * rendering/RenderThemeChromiumWin.h: + +2009-09-22 Beth Dakin <bdakin@apple.com> + + Reviewed by Dave Hyatt. + + Fix for <rdar://problem/6925121> SAP: Wrong width calculation in + table with fixed layout + -and corresponding- + https://bugs.webkit.org/show_bug.cgi?id=29501 + + New Tests: + * fast/table/fixed-table-with-percent-inside-percent-table.html: Added. + * fast/table/fixed-table-with-percent-width-inside-auto-table.html: Added. + * fast/table/fixed-table-with-percent-width-inside-div.html: Added. + * fast/table/fixed-table-with-percent-width-inside-extra-large-div.html: Added. + * fast/table/fixed-table-with-percent-width-inside-fixed-width-table.html: Added. + * fast/table/fixed-table-with-small-percent-width.html: Added. + + This new quirk is very similar to an existing one that was + implemented in revision 4316. + * rendering/FixedTableLayout.cpp: + (WebCore::FixedTableLayout::calcPrefWidths): + +2009-09-22 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Timothy Hatcher. + + List HTTP status code with response headers in resources tab of Web Inspector. + http://webkit.org/b/19945 + + This patch adds a new top level list in the resources tab, HTTP Information, that + for now, contains the Request Method (GET, POST, etc.) and the Status Code (200, 404, etc.). + Additionally, it adds a colored dot next to the requested URL to show the status + (green for success, orange for redirect, red for error). + + * English.lproj/localizedStrings.js: + * inspector/front-end/ImageView.js: + (WebInspector.ImageView): + * inspector/front-end/Images/errorRedDot.png: Added. + * inspector/front-end/Images/successGreenDot.png: Added. + * inspector/front-end/Images/warningOrangeDot.png: Added. + * inspector/front-end/Resource.js: + (WebInspector.Resource.StatusTextForCode): + * inspector/front-end/ResourceView.js: + (WebInspector.ResourceView): + (WebInspector.ResourceView.prototype._refreshURL): + (WebInspector.ResourceView.prototype._refreshHTTPInformation): + * inspector/front-end/inspector.css: + +2009-09-22 Brady Eidson <beidson@apple.com> + + Reviewed by Darin Adler. + + Back list isn't properly updated for fragment changes after a redirect. + <rdar://problem/6142803> and https://bugs.webkit.org/show_bug.cgi?id=20355 + + Test: fast/loader/fragment-after-redirect-gets-back-entry.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURL): Properly reset the policy FrameLoadType before + consulting the policy delegate for fragment scrolling. + +2009-09-22 Darin Fisher <darin@chromium.org> + + Reviewed by Dimitri Glazkov. + + Drop down selects get stuck in the non-visible state and cannot be opened. + https://bugs.webkit.org/show_bug.cgi?id=29645 + + All paths that lead to hiding the popup menu must call popupDidHide on + the PopupMenuClient. This change makes it so by moving all of the + hiding logic to PopupListBox::hidePopup. + + * platform/chromium/PopupMenuChromium.cpp: + (WebCore::PopupContainer::hidePopup): + (WebCore::PopupListBox::hidePopup): + * platform/chromium/PopupMenuChromium.h: + +2009-09-22 Patrick Mueller <Patrick_Mueller@us.ibm.com> + + Reviewed by Timothy Hatcher. + + WebInspector.log() function not protected if console not yet created + https://bugs.webkit.org/show_bug.cgi?id=29336 + + No new tests. Only affects Web Inspector developers adding logging + to their code during development. + + * inspector/front-end/inspector.js: + (WebInspector.log.isLogAvailable): + (WebInspector.log.flushQueue): + (WebInspector.log.flushQueueIfAvailable): + (WebInspector.log.logMessage): + (WebInspector.log): + +2009-09-22 Yaar Schnitman <yaar@chromium.org> + + Reviewed by David Levin. + + Ported chromium.org's webcore.gyp for the webkit chromium port. + + https://bugs.webkit.org/show_bug.cgi?id=29617 + + * WebCore.gyp/WebCore.gyp: Added. + +2009-09-22 Christian Plesner Hansen <christian.plesner.hansen@gmail.com> + + Reviewed by Adam Barth. + + [v8] Don't keep clean wrappers artificially alive + We currently keep all DOM node wrappers alive, even when there are + no more references to them from JS, in case they have properties + that we need to keep around if new JS references are created. + This changes the policy to only keep wrappers artificially alive + if they have changed since they were created. Empty wrappers are + discarded and recreated as needed. + https://bugs.webkit.org/show_bug.cgi?id=29330 + + * bindings/v8/V8GCController.cpp: + (WebCore::ObjectGrouperVisitor::visitDOMWrapper): + +2009-09-22 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: console.count and console.timeEnd + crash when inspector is opened. + + https://bugs.webkit.org/show_bug.cgi?id=29632 + + * inspector/InspectorFrontend.cpp: + (WebCore::InspectorFrontend::addMessageToConsole): + +2009-09-22 Adam Barth <abarth@webkit.org> + + Unreviewed. + + Fix bogus build fix I did last night. + + * bindings/v8/custom/V8DOMWindowCustom.cpp: + (WebCore::V8Custom::WindowSetTimeoutImpl): + +2009-09-22 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + NPAPI/Mac: Don't paint plugins if we don't have a CGContextRef + + * plugins/mac/PluginViewMac.cpp: + +2009-09-22 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reivewed by Simon Hausmann. + + Fix the Qt/Mac build after r48604 (Implement new QWebPageClient class) + + There's no QWidget::x11Info() on Mac, and setPlatformPluginWidget() + takes a QWidget*, not a QWebPageClient* + + * plugins/mac/PluginViewMac.cpp: + (WebCore::PluginView::platformStart): + +2009-09-21 Adam Barth <abarth@webkit.org> + + Attempted fix for the V8 build. + + * bindings/v8/custom/V8DOMWindowCustom.cpp: + (WebCore::V8Custom::WindowSetTimeoutImpl): + +2009-09-21 Adam Barth <abarth@webkit.org> + + Reviewed by Sam Weinig. + + Don't re-enter JavaScript after performing access checks + https://bugs.webkit.org/show_bug.cgi?id=29531 + + Moved the access check slightly later in this functions to avoid + re-entering the JavaScript interpreter (typically via toString) + after performing the access check. + + I can't really think of a meaningful test for this change. It's more + security hygiene. + + * bindings/js/JSDOMWindowCustom.cpp: + (WebCore::JSDOMWindow::setLocation): + (WebCore::JSDOMWindow::open): + (WebCore::JSDOMWindow::showModalDialog): + * bindings/js/JSLocationCustom.cpp: + (WebCore::JSLocation::setHref): + (WebCore::JSLocation::replace): + (WebCore::JSLocation::assign): + * bindings/v8/custom/V8DOMWindowCustom.cpp: + (WebCore::V8Custom::WindowSetTimeoutImpl): + (WebCore::if): + (CALLBACK_FUNC_DECL): + (V8Custom::WindowSetLocation): + (V8Custom::ClearTimeoutImpl): + * bindings/v8/custom/V8LocationCustom.cpp: + (WebCore::ACCESSOR_SETTER): + (WebCore::CALLBACK_FUNC_DECL): + +2009-09-21 Dumitru Daniliuc <dumi@chromium.org> + + Reviewed by Eric Seidel. + + Make all write transaction start with a BEGIN IMMEDIATE command + instead of BEGIN. + + We cannot test this change in a layout test, because in order to + test it we need to spawn two database threads and execute + transaction steps on these two threads in a very specific order, + which seems impossible to do when they share the same main thread + (as they would in a layout test). The SQLite docs and the case + described in the bug though should be enough proof that we do have + a problem here and that this patch will fix it. + + Relevant SQLite documentation: + http://www.sqlite.org/lang_transaction.html + http://www.sqlite.org/lockingv3.html#locking + + https://bugs.webkit.org/show_bug.cgi?id=29218 + + * platform/sql/SQLiteTransaction.cpp: + (WebCore::SQLiteTransaction::SQLiteTransaction): Added a readOnly + parameter. + (WebCore::SQLiteTransaction::begin): Changed to BEGIN IMMEDIATE + for write transactions. + * platform/sql/SQLiteTransaction.h: + * storage/SQLTransaction.cpp: + (WebCore::SQLTransaction::openTransactionAndPreflight): Passing + the read-only flag to the SQLiteTransaction instance. + +2009-09-21 Brady Eidson <beidson@apple.com> + + Rubberstamped by Mark Rowe. + + * DerivedSources.make: Fix the Xcode build on SnowLeopard. + +2009-09-15 John Abd-El-Malek <jam@chromium.org> + + Reviewed by Darin Fisher. + + Prevent sleeps in unload handlers. + https://bugs.webkit.org/show_bug.cgi?id=29193 + + Test: fast/dom/Window/slow_unload_handler.html + + * WebCore.gypi: + * bindings/v8/DateExtension.cpp: Added. + (WebCore::DateExtension::DateExtension): + (WebCore::DateExtension::get): + (WebCore::DateExtension::setAllowSleep): + (WebCore::DateExtension::GetNativeFunction): + (WebCore::DateExtension::weakCallback): + (WebCore::DateExtension::GiveEnableSleepDetectionFunction): + (WebCore::DateExtension::OnSleepDetected): + * bindings/v8/DateExtension.h: Added. + * bindings/v8/V8AbstractEventListener.cpp: + (WebCore::V8AbstractEventListener::invokeEventHandler): + * bindings/v8/V8Proxy.cpp: + (WebCore::V8Proxy::createNewContext): + (WebCore::V8Proxy::registerExtensionWithV8): + (WebCore::V8Proxy::registeredExtensionWithV8): + * bindings/v8/V8Proxy.h: + +2009-09-21 Jian Li <jianli@chromium.org> + + Reviewed by David Levin. + + [V8] Run-time exception in onmessage handler is not forwarded to the + worker object. + https://bugs.webkit.org/show_bug.cgi?id=28980 + + The previous fix was partially reverted due to a reliability build break + in chromium. The break happens when an exception is thrown without + setting a message. We need to check for this scenario and handle it. + + Tested by worker-close.html. + + * bindings/v8/V8AbstractEventListener.cpp: + (WebCore::V8AbstractEventListener::invokeEventHandler): + * bindings/v8/V8Utilities.cpp: + (WebCore::reportException): + +2009-09-21 Greg Bolsinga <bolsinga@apple.com> + + Reviewed by Simon Fraser & Sam Weinig. + + Add ENABLE(ORIENTATION_EVENTS) + https://bugs.webkit.org/show_bug.cgi?id=29508 + + See documentation here: + http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW16 + + * DerivedSources.make: Use new WebCore.OrientationEvents.exp file if ENABLE_ORIENTATION_EVENTS. + Add ENABLE_ORIENTATION_EVENTS to the new ADDITIONAL_IDL_DEFINES variable that is passed to the IDL + code generator. This is because ENABLE_ORIENTATION_EVENTS is not in FEATURE_DEFINES. + * WebCore.OrientationEvents.exp: Added. + * WebCore.xcodeproj/project.pbxproj: Add WebCore.OrientationEvents.exp. + * dom/EventNames.h: Add onorientationchange. + * html/HTMLAttributeNames.in: Ditto. + * html/HTMLBodyElement.cpp: Handle onorientationchange properly. + (WebCore::HTMLBodyElement::parseMappedAttribute): + (WebCore::HTMLBodyElement::onorientationchange): + (WebCore::HTMLBodyElement::setOnorientationchange): + * html/HTMLBodyElement.h: Ditto. + * html/HTMLBodyElement.idl: Ditto. + * html/HTMLFrameSetElement.cpp: Ditto. + (WebCore::HTMLFrameSetElement::parseMappedAttribute): + (WebCore::HTMLFrameSetElement::onorientationchange): + (WebCore::HTMLFrameSetElement::setOnorientationchange): + * html/HTMLFrameSetElement.h: Ditto. + * html/HTMLFrameSetElement.idl: Ditto. + * page/DOMWindow.cpp: Ditto. + (WebCore::DOMWindow::orientation): Calls up the to the Frame for the orientation value. + (WebCore::DOMWindow::onorientationchange): + (WebCore::DOMWindow::setOnorientationchange): + * page/DOMWindow.h: Handle onorientationchange properly. + * page/DOMWindow.idl: Ditto. + * page/Frame.cpp: Ditto. + (WebCore::Frame::Frame): + (WebCore::Frame::sendOrientationChangeEvent): + * page/Frame.h: Ditto. + (WebCore::Frame::orientation): + +2009-09-18 Anders Carlsson <andersca@apple.com> + + Try fixing the build again. + + * platform/win/PopupMenuWin.cpp: + (WebCore::PopupMenu::wndProc): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: completions are always evaluated against + window (discarding call frames). + + https://bugs.webkit.org/show_bug.cgi?id=29616 + + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleView.prototype.completions): + * inspector/front-end/InjectedScript.js: + (InjectedScript.getCompletions): + * inspector/front-end/ScriptsPanel.js: + (WebInspector.ScriptsPanel.prototype.selectedCallFrameId): + +2009-09-21 Brent Fulgham <bfulgham@webkit.org> + + Unreviewed build fix for Windows (Cairo) target. + + Add stubs for SocketStream classes added in @r47788, which + broke the WinCairo build. + + No new tests. (Build failure). + + * WebCore.vcproj/WebCore.vcproj: Add references to new files + to Cairo build, exclude from standard Apple build. + * platform/network/curl/SocketStreamError.h: Added. + * platform/network/curl/SocketStreamHandle.h: Added. + * platform/network/curl/SocketStreamHandleCurl.cpp: Added. + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Expose InspectorResource fields. + + https://bugs.webkit.org/show_bug.cgi?id=29537 + + * inspector/InspectorResource.cpp: + (WebCore::InspectorResource::sourceString): + (WebCore::InspectorResource::resourceData): + * inspector/InspectorResource.h: + (WebCore::InspectorResource::requestHeaderFields): + (WebCore::InspectorResource::responseHeaderFields): + (WebCore::InspectorResource::responseStatusCode): + (WebCore::InspectorResource::requestMethod): + (WebCore::InspectorResource::requestFormData): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: JS error drilling down childless node. + No need to dispatch double click twice - it is already handled + in TreeElement.treeElementDoubleClicked. + + https://bugs.webkit.org/show_bug.cgi?id=22144 + + * inspector/front-end/ElementsTreeOutline.js: + (WebInspector.ElementsTreeOutline): + +2009-09-21 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Implement new QWebPageClient class and let our classes + QWebViewPrivate and QWebGraphicsItemPrivate inherit from it. + + For Qt, platformPageClient() will now return a class derived from + the QWebPageClient, so the patch adapts our Qt hooks to go though + this class and not depend on the QWebView. + + * WebCore.pro: + * platform/Widget.h: + * platform/qt/PlatformScreenQt.cpp: + (WebCore::screenDepth): + (WebCore::screenDepthPerComponent): + (WebCore::screenIsMonochrome): + (WebCore::screenRect): + (WebCore::screenAvailableRect): + * platform/qt/PopupMenuQt.cpp: + (WebCore::PopupMenu::show): + * platform/qt/QWebPageClient.h: Added. + * platform/qt/WidgetQt.cpp: + (WebCore::Widget::setCursor): + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::handleKeyboardEvent): + (WebCore::PluginView::getValue): + (WebCore::PluginView::platformStart): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Evaluating on call frame always returns "undefined". + + https://bugs.webkit.org/show_bug.cgi?id=29613 + + * inspector/front-end/InjectedScript.js: + (InjectedScript.evaluate): + (InjectedScript._evaluateAndWrap): + (InjectedScript._evaluateOn): + (InjectedScript.evaluateInCallFrame): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Exception formatting is broken in console. + + https://bugs.webkit.org/show_bug.cgi?id=29608 + + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleCommandResult): + * inspector/front-end/InjectedScript.js: + (InjectedScript.evaluate): + (InjectedScript.createProxyObject): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Console object formatting is broken. + + https://bugs.webkit.org/show_bug.cgi?id=29607 + + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleMessage.prototype._format): + * inspector/front-end/ObjectProxy.js: + (WebInspector.ObjectProxy.wrapPrimitiveValue): + +2009-09-21 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Crash When Logging an Element Before Opening Inspector + + https://bugs.webkit.org/show_bug.cgi?id=29514 + + * inspector/InspectorController.cpp: + (WebCore::InspectorController::populateScriptObjects): + +2009-09-21 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Incorrect clipping with accelerated compositing content, and position:fixed + https://bugs.webkit.org/show_bug.cgi?id=29347 + + Fix the compositing clipping logic to behave correctly when position:fixed + elements clip, by using the new backgroundClipRect() method to determine + when we need to clip, and to compute the clipping layer position. + + Test: compositing/overflow/fixed-position-ancestor-clip.html + + * rendering/RenderLayerBacking.cpp: + (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): + * rendering/RenderLayerCompositor.cpp: + (WebCore::RenderLayerCompositor::clippedByAncestor): + +2009-09-21 Nate Chapin <japhet@chromium.org> + + Reviewed by Adam Barth. + + Add back in a special case for window.top in the V8 bindings. + + https://bugs.webkit.org/show_bug.cgi?id=29605 + + Fixes LayoutTests/fast/dom/Window/window-property-shadowing.html in the Chromium port. + + * bindings/scripts/CodeGeneratorV8.pm: Ensure window.top is not marked as read only, as this breaks the shadowing disabling. + +2009-09-21 Eric Carlson <eric.carlson@apple.com> + + Reviewed by Brady Eidson. + + HTMLMediaElement: media file should not reload when page comes out of page cache + https://bugs.webkit.org/show_bug.cgi?id=29604 + + Test: media/restore-from-page-cache.html + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::userCancelledLoad): Do nothing unless the element + is still loading. Only fire an 'emptied' event if the readyState is HAVE_NOTHING, + otherwise set the network state to NETWORK_IDLE. + +2009-09-21 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey "Sean/Shawn/Shaun" Garen. + + Clarify two FIXMEs. + + * bindings/js/JSHTMLCollectionCustom.cpp: + (WebCore::getNamedItems): + * bindings/js/JSHTMLFormElementCustom.cpp: + (WebCore::JSHTMLFormElement::nameGetter): + +2009-09-21 Darin Fisher <darin@chromium.org> + + Reviewed by Dimitri Glazkov. + + Drop down selects fail to close when a value is selected + https://bugs.webkit.org/show_bug.cgi?id=29582 + + Implement PopupListBox::hidePopup, which was previously + declared but unimplemented. Removes the declaration of + showPopup since that method is not implemented. + + PopupListBox::hidePopup takes care of hiding the popup, + by invoking hidePopup on its parent PopupContainer, and + then informs the PopupMenuClient that popupDidHide. + This mimics the old behavior prior to r48370. + + * platform/chromium/PopupMenuChromium.cpp: + (WebCore::PopupListBox::handleKeyEvent): + (WebCore::PopupListBox::abandon): + (WebCore::PopupListBox::acceptIndex): + (WebCore::PopupListBox::hidePopup): + +2009-09-21 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Rubber-stamped by Simon Hausmann. + + [Qt] Windows build fix. + https://bugs.webkit.org/show_bug.cgi?id=29535 + + * platform/network/qt/DnsPrefetchHelper.cpp: Missing #include "config.h" added. + +2009-09-21 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed make dist build fix. Missing files. + + * GNUmakefile.am: + +2009-09-20 Adam Barth <abarth@webkit.org> + + Reviewed by Maciej Stachowiak. + + Crash when clicking link in unload handler + https://bugs.webkit.org/show_bug.cgi?id=29525 + + Test that the first navigation always wins when the page tries to start + a new navigation in an unload handler. + + Tests: fast/loader/unload-form-about-blank.html + fast/loader/unload-form-post-about-blank.html + fast/loader/unload-form-post.html + fast/loader/unload-form.html + fast/loader/unload-hyperlink.html + fast/loader/unload-javascript-url.html + fast/loader/unload-reload.html + fast/loader/unload-window-location.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURL): + (WebCore::FrameLoader::loadWithDocumentLoader): + +2009-09-18 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Xan Lopez. + + [GTK] Sometimes crashes when a page is destroyed/loads another URL while playing video + https://bugs.webkit.org/show_bug.cgi?id=29496 + + Protect the video sink object, and destroy it in an idle callback + to hopefully avoid a race condition that leads to a crash. + + This is already tested by media/video-seekable.html + + * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: + (WebCore::idleUnref): + (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): + (WebCore::MediaPlayerPrivate::createGSTPlayBin): + +2009-09-19 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed build fix for GTK+ and a blind one for Qt after r48566. + + * GNUmakefile.am: + * WebCore.pro: + +2009-09-19 Sam Weinig <sam@webkit.org> + + Reviewed by Oliver Hunt. + + Fix for https://bugs.webkit.org/show_bug.cgi?id=29519 + Remove JSNameNodeCollection and just use StaticNodeList + + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * WebCoreSources.bkl: + * bindings/js/JSHTMLCollectionCustom.cpp: + (WebCore::getNamedItems): + * bindings/js/JSHTMLFormElementCustom.cpp: + (WebCore::JSHTMLFormElement::nameGetter): + * bindings/js/JSNamedNodesCollection.cpp: Removed. + * bindings/js/JSNamedNodesCollection.h: Removed. + +2009-09-19 Daniel Bates <dbates@webkit.org> + + Reviewed by Adam Barth. + + https://bugs.webkit.org/show_bug.cgi?id=29511 + + Fixes an issue where script code that contains non-ASCII characters may bypass the + XSSAuditor. + + Before performing a comparison between the script source code and input parameters, we + remove all non-ASCII characters, including non-printable ASCII characters from the + script source code and input parameters. + + Tests: http/tests/security/xssAuditor/img-onerror-non-ASCII-char.html + http/tests/security/xssAuditor/img-onerror-non-ASCII-char-default-encoding.html + http/tests/security/xssAuditor/img-onerror-non-ASCII-char2-default-encoding.html + http/tests/security/xssAuditor/img-onerror-non-ASCII-char2.html + + * page/XSSAuditor.cpp: + (WebCore::isNonCanonicalCharacter): Modified to remove all non-ASCII characters, + including non-printable ASCII characters. + +2009-09-19 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Incorrect animation with scale(0) transform (singular matrix) + https://bugs.webkit.org/show_bug.cgi?id=29465 + + Make accelerated scale() and translate() animations go through the component animation + path (rather than just matrix animation) to avoid problems with singular scale matrices, + and be slightly more efficient. + + Test: compositing/transitions/singular-scale-transition.html + + * platform/graphics/mac/GraphicsLayerCA.mm: + (WebCore::getTransformFunctionValue): + (WebCore::getValueFunctionNameForTransformOperation): + +2009-09-19 Alex Milowski <alex@milowski.com> + + Reviewed by Maciej Stachowiak. + + Adds CSS styling and basic DOM element support for MathML + + * DerivedSources.make: + Added user stylesheet and tag factory generation + + * WebCore.xcodeproj/project.pbxproj: + Added new DOM element code + + * css/CSSParser.cpp: + (WebCore::CSSParser::parseAttr): + Added check for document since stylesheet can be added before there is a document + + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::styleForElement): + Added check to add MathML user agent stylesheet + + * css/mathml.css: Added. + MathML user agent stylesheet + + * dom/Document.cpp: + (WebCore::Document::createElement): + Added support for creation of MathML DOM objects + + * dom/Node.h: + (WebCore::Node::isMathMLElement): + Added check method for whether the node is a MathML node + + * mathml: Added. + * mathml/MathMLElement.cpp: Added. + (WebCore::MathMLElement::MathMLElement): + (WebCore::MathMLElement::create): + (WebCore::MathMLElement::createRenderer): + * mathml/MathMLElement.h: Added. + (WebCore::MathMLElement::isMathMLElement): + MathML DOM base class + + + * mathml/MathMLInlineContainerElement.cpp: Added. + (WebCore::MathMLInlineContainerElement::MathMLInlineContainerElement): + (WebCore::MathMLInlineContainerElement::create): + (WebCore::MathMLInlineContainerElement::createRenderer): + * mathml/MathMLInlineContainerElement.h: Added. + Base class for non-text containers + + * mathml/MathMLMathElement.cpp: Added. + (WebCore::MathMLMathElement::MathMLMathElement): + (WebCore::MathMLMathElement::create): + * mathml/MathMLMathElement.h: Added. + Root Math element + + * mathml/mathtags.in: Added. + Element list mappings + + * page/Frame.cpp: + (WebCore::Frame::Frame): + Added MathML name initialization +2009-09-19 Adam Barth <abarth@webkit.org> + + Reviewed by Oliver Hunt. + + Canvas drawn with data URL image raises SECURITY_ERR when toDataUrl() called. + https://bugs.webkit.org/show_bug.cgi?id=29305 + + We need to special-case data URLs when tainting a canvas because we + treat data URLs has having no security origin, unlike other + browsers. The reason we do this is to help sites avoid XSS via data + URLs, but that consideration doesn't apply to canvas taint. + + Also, we were previously incorrectly taking document.domain state + into account when tainting canvas. + + Tests: http/tests/security/canvas-remote-read-data-url-image.html + http/tests/security/canvas-remote-read-data-url-svg-image.html + http/tests/security/canvas-remote-read-remote-image-document-domain.html + + * html/canvas/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::checkOrigin): + (WebCore::CanvasRenderingContext2D::createPattern): + * page/SecurityOrigin.cpp: + (WebCore::SecurityOrigin::taintsCanvas): + * page/SecurityOrigin.h: + +2009-09-18 Simon Fraser <simon.fraser@apple.com> + + Fix stylistic issue raised in code review for previous commit. + + * rendering/RenderLayerBacking.cpp: + (WebCore::hasNonZeroTransformOrigin): + +2009-09-18 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Element is misplaced during opacity transition with certain configuration of transform-origin and clipping + https://bugs.webkit.org/show_bug.cgi?id=29495 + + If an element has zero size, but has a transform origin with absolute values, + then the transform origin would not be applied because it is implemented via + anchorPoint, which is expressed as a fraction of the layer size. + + Work around this by artificially inflating the size of the backing store when we need to. + + Test: compositing/geometry/transfrom-origin-on-zero-size-layer.html + + * rendering/RenderLayerBacking.h: + * rendering/RenderLayerBacking.cpp: + (WebCore::RenderLayerBacking::RenderLayerBacking): + Init m_artificiallyInflatedBounds to false. + + (WebCore::hasNonZeroTransformOrigin): + Utility function that describes whether the transform-origin contains non-percentage + x or y offsets. + + (WebCore::RenderLayerBacking::updateCompositedBounds): + New wrapper method around setCompositedBounds() that applies the size inflation + when necessary, setting the m_artificiallyInflatedBounds as appropriate. + + (WebCore::RenderLayerBacking::updateAfterLayout): Call updateCompositedBounds(). + (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Ditto + + * rendering/RenderLayerCompositor.cpp: + (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Ditto + (WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry): Ditto + +2009-09-18 Antti Koivisto <antti@apple.com> + + Reviewed by Maciej Stachowiak. + + https://bugs.webkit.org/show_bug.cgi?id=29512 + Don't recalculate style when restoring from the page cache + + FrameLoaderClient::forceLayout() also forces style recalc. Instead call FrameView::forceLayout() + directly to update the scrollbars while keeping the existing style. + + Makes back/forward really fast on complex pages (in cases where page cache works). + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::commitProvisionalLoad): + +2009-09-18 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Implement ES5 Object.defineProperty function + https://bugs.webkit.org/show_bug.cgi?id=29503 + + Override defineOwnProperty on JSDOMWindowShell to forward appropriately, + and then override defineOwnProperty on JSDOMWindow to disallow cross origin + defineOwnProperty usage. We also override defineOwnProperty on QuarantinedObjectWrapper + to ensure correct wrapping semantics of quarantined objects. + + One major caveat in this patch is that it currently disallows the use + of Object.defineProperty on DOMObjects other than the window due to + the significant work involved in correctly propagating attributes and + ensuring correct semantics on dom objects. + + Tests: fast/js/Object-defineProperty.html + http/tests/security/xss-DENIED-defineProperty.html + + * bindings/js/JSDOMBinding.cpp: + (WebCore::DOMObject::defineOwnProperty): + * bindings/js/JSDOMBinding.h: + * bindings/js/JSDOMWindowCustom.cpp: + (WebCore::JSDOMWindow::defineGetter): + (WebCore::JSDOMWindow::defineSetter): + (WebCore::JSDOMWindow::defineOwnProperty): + * bindings/js/JSDOMWindowShell.cpp: + (WebCore::JSDOMWindowShell::defineOwnProperty): + (WebCore::JSDOMWindowShell::defineGetter): + (WebCore::JSDOMWindowShell::defineSetter): + * bindings/js/JSDOMWindowShell.h: + * bindings/js/JSLocationCustom.cpp: + (WebCore::JSLocation::defineGetter): + (WebCore::JSLocationPrototype::defineGetter): + * bindings/js/JSQuarantinedObjectWrapper.cpp: + (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyDescriptor): + (WebCore::JSQuarantinedObjectWrapper::defineOwnProperty): + * bindings/js/JSQuarantinedObjectWrapper.h: + * bindings/scripts/CodeGeneratorJS.pm: + +2009-09-18 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=29510 + Active DOM objects should be suspended while a modal dialog is displayed + + * manual-tests/js-timers-beneath-modal-dialog.html: Added a test for JS timers. + + * page/PageGroupLoadDeferrer.cpp: + (WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer): + (WebCore::PageGroupLoadDeferrer::~PageGroupLoadDeferrer): + Match other platforms, and make Mac also suspend active DOM objects. Since a page that + currently displays a modal dialog cannot go into page cache, there is no danger of suspending + an object twice. + +2009-09-18 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Eric Seidel. + + [Qt] Buildfix caused by http://trac.webkit.org/changeset/48513 + https://bugs.webkit.org/show_bug.cgi?id=29351 + + * bridge/qt/qt_instance.h: createRuntimeObject method renamed to newRuntimeObject. + * bridge/runtime.h: Visibility of newRuntimeObject method modified to protected. + +2009-09-18 Yury Semikhatsky <yurys@chromium.org> + + Reviewed by Timothy Hatcher. + + Fix parameter substitutions in console.log(). + + https://bugs.webkit.org/show_bug.cgi?id=29366 + + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleMessage.prototype._format): + * inspector/front-end/InjectedScript.js: + (InjectedScript.getPrototypes): + (InjectedScript.CallFrameProxy.prototype._wrapScopeChain): + * inspector/front-end/utilities.js: + (): + +2009-09-18 Sam Weinig <sam@webkit.org> + + Reviewed by Geoffrey Garen and Brady Eidson. + + Temporarily remove an assertion that was getting hit when going + back to a page in the page cache while a banner in Safari was visible. + We should re-enable this once that is fixed. See <rdar://problem/7218118> + + * page/FrameView.cpp: + (WebCore::FrameView::scheduleRelayout): + +2009-09-18 Anders Carlsson <andersca@apple.com> + + Try fixing the build again. + + * platform/win/PopupMenuWin.cpp: + (WebCore::PopupMenu::wndProc): + +2009-09-18 Anders Carlsson <andersca@apple.com> + + Fix windows build. + + * platform/win/PopupMenuWin.cpp: + +2009-09-18 Sam Weinig <sam@webkit.org> + + Reviewed by Gavin 'BearClaw' Barraclough. + + Convert another callback type object to store the global object + instead of the frame. + + * bindings/js/JSCustomXPathNSResolver.cpp: + (WebCore::JSCustomXPathNSResolver::create): + (WebCore::JSCustomXPathNSResolver::JSCustomXPathNSResolver): + (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI): + * bindings/js/JSCustomXPathNSResolver.h: + +2009-09-18 Anders Carlsson <andersca@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=29332 + <rdar://problem/7231652> + REGRESSION (r48446): While a <select> popup menu is open, the + rest of the WebView doesn't respond to mouse move events. + + * platform/win/PopupMenuWin.cpp: + (WebCore::translatePoint): + New helper function that translates a point between HWND coordinates. + + (WebCore::PopupMenu::show): + Protect the PopupMenu if someone removes the <select> in response to a mouse + event. Handle WM_HOST_WINDOW_MOUSEMOVE events. + + (WebCore::PopupMenu::wndProc): + in the WM_MOUSEMOVE handler, if the mouse is not over the popup, post a + WM_HOST_WINDOW_MOUSEMOVE event so that the host window (the WebView) gets the + mouse move event. + +2009-09-18 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dave Hyatt. + + Compositing layers are incorrectly positioned after scrolling with position:fixed + https://bugs.webkit.org/show_bug.cgi?id=29262 + + When scrolling a page with compositing layers inside a position:fixed element, + we need to update the compositing layer positions when the scroll position changes. + + Test: compositing/geometry/fixed-position.html + + * WebCore.base.exp: + Export FrameView::scrollPositionChanged() + + * page/FrameView.h: + * page/FrameView.cpp: + (WebCore::FrameView::scrollPositionChanged): + New method that sends the scroll event, and updates compositing layers positions if necessary. + +2009-09-18 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dave Hyatt. + + Transformed elements inside position:fixed container are clipped incorrectly + https://bugs.webkit.org/show_bug.cgi?id=29346 + + Fix clipping and hit testing on transformed elements inside a position:fixed element. + Previously, the code used the overflowClipRect of the parent clip rects, but + this is not correct for fixed postion elements. Instead, share code that is + already present in calculateRects() to get the correct rect. + + Test: fast/overflow/position-fixed-transform-clipping.html + + * rendering/RenderLayer.h: + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::paintLayer): + (WebCore::RenderLayer::hitTestLayer): + Call the new backgroundClipRect() to get the correct clipRect. + + (WebCore::RenderLayer::backgroundClipRect): + New method, factored out of calculateRects(), that computes the clip rect, + doing the right thing for fixed position elements. + + (WebCore::RenderLayer::calculateRects): + Call the new backgroundClipRect() method. + +2009-09-18 Dan Bernstein <mitz@apple.com> + + Reviewed by Darin Adler. + + Fix <rdar://problem/7050773> REGRESSION (r40098) Crash at + WebCore::RenderBlock::layoutBlock() + https://bugs.webkit.org/show_bug.cgi?id=29498 + + Test: accessibility/nested-layout-crash.html + + * accessibility/AccessibilityRenderObject.cpp: + (WebCore::AccessibilityRenderObject::updateBackingStore): Changed to + call Document::updateLayoutIgnorePendingStylesheets() instead of + calling RenderObject::layoutIfNeeded(). The latter requires that + there be no pending style recalc, which allows methods that call + Document::updateLayout() to be called during layout without risking + re-entry into layout. + * accessibility/mac/AccessibilityObjectWrapper.mm: + (-[AccessibilityObjectWrapper accessibilityActionNames]): Null-check + m_object after calling updateBackingStore(), since style recalc may + destroy the renderer, which destroys the accessibility object and + detaches it from the wrapper. + (-[AccessibilityObjectWrapper accessibilityAttributeNames]): Ditto. + (-[AccessibilityObjectWrapper accessibilityAttributeValue:]): Ditto. + (-[AccessibilityObjectWrapper accessibilityFocusedUIElement]): Ditto. + (-[AccessibilityObjectWrapper accessibilityHitTest:]): Ditto. + (-[AccessibilityObjectWrapper accessibilityIsAttributeSettable:]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityIsIgnored]): Ditto. + (-[AccessibilityObjectWrapper accessibilityParameterizedAttributeNames]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityPerformPressAction]): Ditto. + (-[AccessibilityObjectWrapper accessibilityPerformIncrementAction]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityPerformDecrementAction]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityPerformAction:]): Ditto. + (-[AccessibilityObjectWrapper accessibilitySetValue:forAttribute:]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityIndexOfChild:]): Ditto. + (-[AccessibilityObjectWrapper accessibilityArrayAttributeCount:]): + Ditto. + (-[AccessibilityObjectWrapper accessibilityArrayAttributeValues:index:maxCount:]): + Ditto. + +2009-09-18 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Simon Hausmann. + + Update Qt build system for Web Socket. + https://bugs.webkit.org/show_bug.cgi?id=29270 + + * WebCore.pro: + * platform/network/qt/SocketStreamError.h: Added. + * platform/network/qt/SocketStreamHandle.h: Added. + * platform/network/qt/SocketStreamHandleSoup.cpp: Added. + +2009-09-18 Eric Carlson <eric.carlson@apple.com> + + Reviewed by Darin Adler. + + NULL check HTMLMediaElement::m_playedTimeRanges. + Fix for https://bugs.webkit.org/show_bug.cgi?id=29494 + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::addPlayedRange): New. Create m_playedTimeRanges if + necessary, add range specified. + (WebCore::HTMLMediaElement::seek): Use addPlayedRange. + (WebCore::HTMLMediaElement::played): Use addPlayedRange. Change time comparison + to be more readable. + (WebCore::HTMLMediaElement::updatePlayState): Ditto. + * html/HTMLMediaElement.h: + +2009-09-18 Sam Weinig <sam@webkit.org> + + Reviewed by Adele Peterson. + + Follow up fix for https://bugs.webkit.org/show_bug.cgi?id=29276 + REGRESSION(r48334): WebKit crashes on file select by drag + + Don't use Document.elementFromPoint since it returns null if the point + is outside the viewport. Instead, just hit test ourselves. + + Test: fast/events/drag-file-crash.html + + * page/DragController.cpp: + (WebCore::elementUnderMouse): + (WebCore::DragController::tryDocumentDrag): + (WebCore::DragController::concludeEditDrag): + +2009-09-18 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Each wrapped Objective-C object should use a single RuntimeObjectImp + https://bugs.webkit.org/show_bug.cgi?id=29351 + rdar://problem/7142294 + + * WebCore.base.exp: Added a newly-needed exported symbol. + + * bindings/objc/DOMInternal.h: Eliminated unused + createWrapperCacheWithIntegerKeys; it has not been needed since the + RGBColor wrappers were reworked. + * bindings/objc/DOMInternal.mm: Ditto. + + * bridge/objc/objc_instance.h: Made the create function non-inline. + * bridge/objc/objc_instance.mm: + (createInstanceWrapperCache): Added. Creates an appropriate map table. + (ObjcInstance::create): Moved here from header. Uses NSMapGet and + NSMapInsert to cache the instance in a map table. + (ObjcInstance::~ObjcInstance): Added a call to NSMapRemove to remove + the instance from the map table. + + * bridge/qt/qt_instance.cpp: + (JSC::Bindings::QtInstance::~QtInstance): Remove unneeded code to remove + the instance from cachedObjects, which no longer exists. + (JSC::Bindings::QtInstance::newRuntimeObject): Renamed to overload new + bottleneck. Caching is now handled by the base class. + + * bridge/runtime.cpp: + (JSC::Bindings::Instance::Instance): Initialize m_runtimeObject to 0. + (JSC::Bindings::Instance::~Instance): Assert m_runtimeObject is 0. + (JSC::Bindings::Instance::createRuntimeObject): Use m_runtimeObject + if it's already set. Set m_runtimeObject and call addRuntimeObject + if it's not. + (JSC::Bindings::Instance::newRuntimeObject): Added. Virtual function, + used only by createRuntimeObject. + (JSC::Bindings::Instance::willDestroyRuntimeObject): Added. + Calls removeRuntimeObject and then clears m_runtimeObject. + (JSC::Bindings::Instance::willInvalidateRuntimeObject): Added. + Clears m_runtimeObject. + + * bridge/runtime.h: Made createRuntimeObject non-virtual. Added + willDestroyRuntimeObject, willInvalidateRuntimeObject, + newRuntimeObject, and m_runtimeObject. + + * bridge/runtime_object.cpp: + (JSC::RuntimeObjectImp::RuntimeObjectImp): Removed addRuntimeObject + call, now handled by caller. + (JSC::RuntimeObjectImp::~RuntimeObjectImp): Replaced removeRuntimeObject + call with willDestroyRuntimeObject call; the latter nows calls + removeRuntimeObject. + (JSC::RuntimeObjectImp::invalidate): Added willInvalidateRuntimeObject + call. + + * bridge/runtime_object.h: Made invalidate non-virtual. + +2009-09-18 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Make PlatformWindow return something else than PlatformWidget + https://bugs.webkit.org/show_bug.cgi?id=29085 + + Make platformWindow return a PlatformPageClient + (for now typedef'ed to PlatformWidget) + + Also, change the name of platformWindow to platformPageClient() + + * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: + (getPangoLayoutForAtk): + * accessibility/win/AXObjectCacheWin.cpp: + (WebCore::AXObjectCache::postPlatformNotification): + (WebCore::AXObjectCache::handleFocusedUIElementChanged): + * loader/EmptyClients.h: + (WebCore::EmptyChromeClient::platformPageClient): + * page/Chrome.cpp: + (WebCore::Chrome::platformPageClient): + * page/Chrome.h: + * page/ChromeClient.h: + * page/mac/EventHandlerMac.mm: + (WebCore::EventHandler::wheelEvent): + (WebCore::EventHandler::currentPlatformMouseEvent): + (WebCore::EventHandler::sendContextMenuEvent): + (WebCore::EventHandler::eventMayStartDrag): + * platform/HostWindow.h: + * platform/Widget.h: + * platform/gtk/PlatformScreenGtk.cpp: + (WebCore::getVisual): + (WebCore::screenRect): + (WebCore::screenAvailableRect): + * platform/gtk/PopupMenuGtk.cpp: + (WebCore::PopupMenu::show): + * platform/gtk/ScrollViewGtk.cpp: + (WebCore::ScrollView::platformAddChild): + (WebCore::ScrollView::platformRemoveChild): + (WebCore::ScrollView::visibleContentRect): + * platform/gtk/WidgetGtk.cpp: + (WebCore::Widget::setFocus): + (WebCore::Widget::setCursor): + * platform/qt/PlatformScreenQt.cpp: + (WebCore::screenDepth): + (WebCore::screenDepthPerComponent): + (WebCore::screenIsMonochrome): + (WebCore::screenRect): + (WebCore::screenAvailableRect): + * platform/qt/PopupMenuQt.cpp: + (WebCore::PopupMenu::show): + * platform/qt/WidgetQt.cpp: + (WebCore::Widget::setCursor): + * platform/win/PlatformScreenWin.cpp: + (WebCore::monitorInfoForWidget): + * platform/win/PopupMenuWin.cpp: + (WebCore::PopupMenu::show): + (WebCore::PopupMenu::calculatePositionAndSize): + (WebCore::PopupMenu::wndProc): + * platform/wx/RenderThemeWx.cpp: + (WebCore::nativeWindowForRenderObject): + * platform/wx/ScrollbarThemeWx.cpp: + (WebCore::ScrollbarThemeWx::paint): + * plugins/gtk/PluginViewGtk.cpp: + (WebCore::PluginView::getValue): + (WebCore::PluginView::forceRedraw): + (WebCore::PluginView::platformStart): + * plugins/mac/PluginViewMac.cpp: + (WebCore::PluginView::platformStart): + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::handleKeyboardEvent): + (WebCore::PluginView::getValue): + (WebCore::PluginView::platformStart): + * plugins/win/PluginViewWin.cpp: + (WebCore::PluginView::getValue): + (WebCore::PluginView::forceRedraw): + (WebCore::PluginView::platformStart): + +2009-09-18 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Web inspector UI adjustments specific to the Qt platform: + - Hide the close button + - Hide the dock button + - Disable the draggable toolbar + + https://bugs.webkit.org/show_bug.cgi?id=29384 + + * inspector/front-end/inspector.css: + * inspector/front-end/inspector.js: + (WebInspector.toolbarDragStart): + +2009-09-18 Joerg Bornemann <joerg.bornemann@nokia.com> + + Reviewed by Simon Hausmann. + + QtWebKit Windows CE compile fixes + + Exclude certain pure-WINCE specific code paths from the Qt build. + + * platform/graphics/BitmapImage.h: + * platform/graphics/FontCache.h: + * platform/graphics/MediaPlayer.cpp: + * platform/text/TextEncodingRegistry.cpp: + (WebCore::buildBaseTextCodecMaps): + (WebCore::extendTextCodecMaps): + * plugins/PluginView.cpp: + (WebCore::PluginView::stop): Guard this code block with NETSCAPE_PLUGIN_API as + the corresponding PluginViewWndProc has the same guard in the header file. + +2009-09-18 Steve Block <steveblock@google.com> + + Reviewed by Dimitri Glazkov. + + Geolocation does not correctly handle Infinity for PositionOptions properties. + https://bugs.webkit.org/show_bug.cgi?id=29099 + + * bindings/js/JSGeolocationCustom.cpp: Modified. + (WebCore::createPositionOptions): Modified. If timeout or maximumAge is positive infinity, applies these values as a special case. + * page/PositionOptions.h: Modified. + (WebCore::PositionOptions::hasMaximumAge): Added. Determines whether the object has a maximum age. + (WebCore::PositionOptions::maximumAge): Modified. Asserts that the object has a maximum age. + (WebCore::PositionOptions::clearMaximumAge): Added. Clears the maximum age. + (WebCore::PositionOptions::setMaximumAge): Modified. Registers that the maximum age has been set. + (WebCore::PositionOptions::PositionOptions): Modified. Registers that the maximum age has been set. + +2009-09-17 Sam Weinig <sam@webkit.org> + + Reviewed by Adele Peterson. + + Fix for https://bugs.webkit.org/show_bug.cgi?id=29276 + REGRESSION(r48334): WebKit crashes on file select by drag + + Document.elementFromPoint now takes point in client space, not page space. + + * page/DragController.cpp: + (WebCore::DragController::tryDocumentDrag): + (WebCore::DragController::concludeEditDrag): + +2009-09-17 Albert J. Wong <ajwong@chromium.org> + + Reviewed by David Levin. + + Reimplement default media UI for Mac Chromium to match the style + of the Windows and Linux versions. Also breaks the dependency + on the internal wk* functions that were previously used to + render the media controller widgets. + https://bugs.webkit.org/show_bug.cgi?id=29161 + + No media layout tests are currently enabled in Mac Chromium, so + nothing needs rebaselineing, etc. + + This is a recommit of r48438 with a compile fix and merges of + recent changes to the file. + + * css/mediaControlsChromium.css: + * rendering/RenderThemeChromiumMac.h: + * rendering/RenderThemeChromiumMac.mm: + (WebCore::mediaElementParent): + (WebCore::RenderThemeChromiumMac::extraMediaControlsStyleSheet): + (WebCore::mediaSliderThumbImage): + (WebCore::mediaVolumeSliderThumbImage): + (WebCore::RenderThemeChromiumMac::paintSliderTrack): + (WebCore::RenderThemeChromiumMac::adjustSliderThumbSize): + (WebCore::RenderThemeChromiumMac::paintMediaButtonInternal): + (WebCore::RenderThemeChromiumMac::paintMediaPlayButton): + (WebCore::RenderThemeChromiumMac::paintMediaMuteButton): + (WebCore::RenderThemeChromiumMac::paintMediaSliderTrack): + (WebCore::RenderThemeChromiumMac::paintMediaVolumeSliderTrack): + (WebCore::RenderThemeChromiumMac::paintMediaSliderThumb): + (WebCore::RenderThemeChromiumMac::paintMediaVolumeSliderThumb): + (WebCore::RenderThemeChromiumMac::paintMediaControlsBackground): + * rendering/RenderThemeChromiumSkia.cpp: + (WebCore::RenderThemeChromiumSkia::adjustSliderThumbSize): + +2009-09-17 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Timothy Hatcher. + + The Console scope bar should have a divider between All and the other possible + values (Errors, Warnings, Logs). It will look something like: + + All | Errors Warnings Logs. + + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleView.createDividerElement): + (WebInspector.ConsoleView): + * inspector/front-end/inspector.css: + +2009-09-17 Sam Weinig <sam@webkit.org> + + Reviewed by Mark Rowe. + + Remove additional references to JSVoidCallback which no longer exists. + + * DerivedSources.cpp: + * WebCore.vcproj/WebCore.vcproj: + +2009-09-17 Sam Weinig <sam@webkit.org> + + Reviewed by Brady Eidson. + + Remove commented out onhashchange attribute now that it is implemented. + + * page/DOMWindow.idl: + +2009-09-17 Anders Carlsson <andersca@apple.com> + + Reviewed by Oliver Hunt. + + <rdar://problem/7007541> + CrashTracer: 4800+ crashes in Safari at com.apple.WebKit • WTF::HashTableIterator... + + Make RuntimeObjectImp more robust against m_instance being a null (which can happen if an OOP plug-in + crashes while we're calling into it). + + * bridge/runtime_object.cpp: + (JSC::RuntimeObjectImp::RuntimeObjectImp): + (JSC::RuntimeObjectImp::~RuntimeObjectImp): + (JSC::RuntimeObjectImp::invalidate): + (JSC::RuntimeObjectImp::fallbackObjectGetter): + (JSC::RuntimeObjectImp::fieldGetter): + (JSC::RuntimeObjectImp::methodGetter): + (JSC::RuntimeObjectImp::getOwnPropertySlot): + (JSC::RuntimeObjectImp::getOwnPropertyDescriptor): + (JSC::RuntimeObjectImp::put): + (JSC::RuntimeObjectImp::defaultValue): + (JSC::RuntimeObjectImp::getCallData): + (JSC::RuntimeObjectImp::getConstructData): + (JSC::RuntimeObjectImp::getPropertyNames): + * bridge/runtime_object.h: + (JSC::RuntimeObjectImp::getInternalInstance): + +2009-09-17 Yury Semikhatsky <yurys@chromium.org> + + Reviewed by Timothy Hatcher. + + Wrap primitive values (as objects) in InspectorController::wrap. + + https://bugs.webkit.org/show_bug.cgi?id=28983 + + * inspector/InspectorController.cpp: + (WebCore::InspectorController::wrapObject): objects of any type will be wrapped into proxies, + only object proxies will have objectId. + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleView.prototype.completions): there is InjectedScript.getCompletionsi + that accepts an expression and returns possible completions. This way we don't need to wrap + and unwrap the completions result into a proxy object. + * inspector/front-end/InjectedScript.js: + (InjectedScript.getCompletions): + (InjectedScript.evaluate): + (InjectedScript._evaluateOn): + (InjectedScript.createProxyObject): + * inspector/front-end/InjectedScriptAccess.js: + +2009-09-17 Nate Chapin <japhet@chromium.org> + + Reviewed by Dimitri Glazkov. + + Wrap PageTransitionEvents properly for V8's use. + + https://bugs.webkit.org/show_bug.cgi?id=29340 + + Fixes Chromium's failures for LayoutTests/fast/events/pageshow-pagehide.html. + + * bindings/v8/V8DOMWrapper.cpp: + (WebCore::V8DOMWrapper::convertEventToV8Object): Wrap PageTransitionEvents properly. + +2009-09-17 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dave Hyatt. + + Hardware-accelerated opacity transition on inline asserts + https://bugs.webkit.org/show_bug.cgi?id=29342 + + Remove an erroneous toRenderBox() that could be called on a RenderInline; we can just + pass an empty size, because the box size is only required for transform animations. + + Test: compositing/transitions/opacity-on-inline.html + + * rendering/RenderLayerBacking.cpp: + (WebCore::RenderLayerBacking::startTransition): + +2009-09-17 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + [V8] OwnHandle might get a weak callback after destruction + https://bugs.webkit.org/show_bug.cgi?id=29172 + + Be sure to clear out weak reference so we don't get a weak callback + after we've destructed ourselves. Also, removed some tricky methods + that had no clients. + + * bindings/v8/OwnHandle.h: + (WebCore::OwnHandle::clear): + +2009-09-17 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed, build fix. + + [V8] Partial roll out of http://trac.webkit.org/changeset/48455 to + fix crashes that started happening in V8Proxy::getEnteredContext(). + + * bindings/v8/ScheduledAction.cpp: + (WebCore::ScheduledAction::execute): + +2009-09-17 Chris Fleizach <cfleizach@apple.com> + + Reviewed by Beth Dakin. + + AX: labels of checkboxes should, when hit-tested, return the checkbox + https://bugs.webkit.org/show_bug.cgi?id=29335 + + When an accessibility hit test is done and it hits the label of a control element, + the control element should be returned instead of nothing, since the label + itself is usually ignored. + + Test: accessibility/label-for-control-hittest.html + + * accessibility/AccessibilityObject.h: + (WebCore::AccessibilityObject::correspondingControlForLabelElement): + * accessibility/AccessibilityRenderObject.cpp: + (WebCore::AccessibilityRenderObject::accessibilityIsIgnored): + (WebCore::AccessibilityRenderObject::doAccessibilityHitTest): + (WebCore::AccessibilityRenderObject::correspondingControlForLabelElement): + * accessibility/AccessibilityRenderObject.h: + +2009-09-17 Avi Drissman <avi@chromium.org> + + Reviewed by Dimitri Glazkov, build fix. + + Change to make RenderThemeChromiumMac compile inside of non PLATFORM(MAC). + https://bugs.webkit.org/show_bug.cgi?id=29243 + + Covered by existing tests. + + * rendering/RenderThemeChromiumMac.mm: + (WebCore::RenderThemeChromiumMac::paintMediaSliderTrack): + +2009-09-17 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Eric Seidel. + + [V8] Accessing properties/methods of an object, created with document.implementation.createDocumentType + creates nodes that have no document (ScriptExecutionContext), which in turn produces NULL-ref crashes. + https://bugs.webkit.org/show_bug.cgi?id=26402 + + Test: fast/dom/DOMImplementation/detached-doctype.html + fast/dom/doctype-event-listener-crash.html + + * bindings/v8/V8DOMWrapper.cpp: + (WebCore::V8DOMWrapper::getEventListener): Added an extra NULL-check. + +2009-09-17 Dan Bernstein <mitz@apple.com> + + Reviewed by Simon Fraser. + + FontDescription.h includes RenderStyleConstants.h, which violates layering + https://bugs.webkit.org/show_bug.cgi?id=29327 + + * GNUmakefile.am: Added FontSmoothingMode.h. + * WebCore.gypi: Added FontSmoothingMode.h. + * WebCore.vcproj/WebCore.vcproj: Added FontSmoothingMode.h. + * WebCore.xcodeproj/project.pbxproj: Added FontSmoothingMode.h and made + it a private header. + * css/CSSComputedStyleDeclaration.cpp: + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Get the + font smoothing mode via the font description. + * css/CSSPrimitiveValueMappings.h: Include FontSmoothingMode.h + (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Updated for the rename + of FontSmoothing to FontSmoothingMode. + (WebCore::CSSPrimitiveValue::operator FontSmoothingMode): Ditto. + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::applyProperty): Get the font smoothing mode + via the font description. + * platform/graphics/FontDescription.h: Do not include + RenderStyleConstants.h. + (WebCore::FontDescription::fontSmoothing): Updated for the rename of + FontSmoothing to FontSmoothingMode. + (WebCore::FontDescription::setFontSmoothing): Ditto. + * platform/graphics/FontSmoothingMode.h: Added. + (WebCore::FontSmoothingMode): Moved the FontSmoothing enum from + RenderStyleConstants here and renamed it to this. + * rendering/style/RenderStyle.h: + (WebCore::InheritedFlags::fontSmoothing): Removed this getter, since + this can be accessed via the font description. + * rendering/style/RenderStyleConstants.h: Moved the FontSmoothing enum + from here to FontSmoothingMode.h. + +2009-09-17 Kevin Ollivier <kevino@theolliviers.com> + + wx 2.9 build fix. + + * platform/wx/wxcode/gtk/scrollbar_render.cpp: + (wxGetGdkWindowForDC): + +2009-09-16 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Elements appear behind <video> when they should be in front sometimes + https://bugs.webkit.org/show_bug.cgi?id=29314 + + r45598 added logic that tests for overlap with <video> to determine when to throw + a layer into compositing mode. That logic was incorrect in some cases, and this patch + fixes it. When testing overlap, the layer needs to be composited iff some previous layer + is composited (which adds a rect to the overlay map), and there is overlap. + + Test: compositing/geometry/video-opacity-overlay.html + + * rendering/RenderLayerCompositor.cpp: + (WebCore::CompositingState::CompositingState): + (WebCore::RenderLayerCompositor::computeCompositingRequirements): + +2009-09-17 Avi Drissman <avi@google.com> + + Reviewed by Darin Fisher. + + Update the Chromium Mac theming files (RenderTheme and Theme) to be + up-to-date. + + https://bugs.webkit.org/show_bug.cgi?id=29243 + http://crbug.com/19604 + + Covered by existing tests. + + * WebCore.gypi: + * platform/chromium/ThemeChromiumMac.h: Added. + (WebCore::ThemeChromiumMac::ThemeChromiumMac): + (WebCore::ThemeChromiumMac::~ThemeChromiumMac): + (WebCore::ThemeChromiumMac::controlRequiresPreWhiteSpace): + * platform/chromium/ThemeChromiumMac.mm: Added. + (WebCore::): + (WebCore::platformTheme): + (WebCore::controlSizeForFont): + (WebCore::sizeFromFont): + (WebCore::setControlSize): + (WebCore::updateStates): + (WebCore::inflateRect): + (WebCore::checkboxSizes): + (WebCore::checkboxMargins): + (WebCore::checkboxSize): + (WebCore::checkbox): + (WebCore::paintCheckbox): + (WebCore::radioSizes): + (WebCore::radioMargins): + (WebCore::radioSize): + (WebCore::radio): + (WebCore::paintRadio): + (WebCore::buttonSizes): + (WebCore::buttonMargins): + (WebCore::button): + (WebCore::paintButton): + (WebCore::ThemeChromiumMac::baselinePositionAdjustment): + (WebCore::ThemeChromiumMac::controlFont): + (WebCore::ThemeChromiumMac::controlSize): + (WebCore::ThemeChromiumMac::minimumControlSize): + (WebCore::ThemeChromiumMac::controlBorder): + (WebCore::ThemeChromiumMac::controlPadding): + (WebCore::ThemeChromiumMac::inflateControlPaintRect): + (WebCore::ThemeChromiumMac::paint): + * platform/graphics/FloatPoint.h: + * platform/graphics/FloatRect.h: + * platform/graphics/FloatSize.h: + * platform/graphics/IntRect.h: + * rendering/RenderThemeChromiumMac.h: + (WebCore::RenderThemeChromiumMac::supportsControlTints): + (WebCore::RenderThemeChromiumMac::scrollbarControlSizeForPart): + (WebCore::RenderThemeChromiumMac::supportsSelectionForegroundColors): + * rendering/RenderThemeChromiumMac.mm: + (-[WebCoreRenderThemeNotificationObserver systemColorsDidChange:]): + (-[RTCMFlippedView isFlipped]): + (-[RTCMFlippedView currentEditor]): + (WebCore::): + (WebCore::FlippedView): + (WebCore::RenderTheme::themeForPage): + (WebCore::RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor): + (WebCore::RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor): + (WebCore::RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor): + (WebCore::RenderThemeChromiumMac::systemFont): + (WebCore::convertNSColorToColor): + (WebCore::menuBackgroundColor): + (WebCore::RenderThemeChromiumMac::systemColor): + (WebCore::RenderThemeChromiumMac::isControlStyled): + (WebCore::RenderThemeChromiumMac::adjustRepaintRect): + (WebCore::RenderThemeChromiumMac::inflateRect): + (WebCore::RenderThemeChromiumMac::convertToPaintingRect): + (WebCore::RenderThemeChromiumMac::setFontFromControlSize): + (WebCore::RenderThemeChromiumMac::paintTextField): + (WebCore::RenderThemeChromiumMac::paintCapsLockIndicator): + (WebCore::RenderThemeChromiumMac::paintTextArea): + (WebCore::RenderThemeChromiumMac::paintMenuList): + (WebCore::TopGradientInterpolate): + (WebCore::BottomGradientInterpolate): + (WebCore::MainGradientInterpolate): + (WebCore::TrackGradientInterpolate): + (WebCore::RenderThemeChromiumMac::paintMenuListButtonGradients): + (WebCore::RenderThemeChromiumMac::paintMenuListButton): + (WebCore::RenderThemeChromiumMac::popupInternalPaddingLeft): + (WebCore::RenderThemeChromiumMac::popupInternalPaddingRight): + (WebCore::RenderThemeChromiumMac::popupInternalPaddingTop): + (WebCore::RenderThemeChromiumMac::popupInternalPaddingBottom): + (WebCore::RenderThemeChromiumMac::adjustMenuListButtonStyle): + (WebCore::RenderThemeChromiumMac::adjustSliderTrackStyle): + (WebCore::RenderThemeChromiumMac::adjustSliderThumbStyle): + (WebCore::RenderThemeChromiumMac::paintSliderThumb): + (WebCore::RenderThemeChromiumMac::paintSearchField): + (WebCore::RenderThemeChromiumMac::setSearchCellState): + (WebCore::RenderThemeChromiumMac::adjustSearchFieldStyle): + (WebCore::RenderThemeChromiumMac::paintSearchFieldCancelButton): + (WebCore::RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle): + (WebCore::RenderThemeChromiumMac::adjustSearchFieldDecorationStyle): + (WebCore::RenderThemeChromiumMac::paintSearchFieldDecoration): + (WebCore::RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle): + (WebCore::RenderThemeChromiumMac::paintSearchFieldResultsDecoration): + (WebCore::RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle): + (WebCore::RenderThemeChromiumMac::paintSearchFieldResultsButton): + (WebCore::mediaControllerTheme): + (WebCore::RenderThemeChromiumMac::adjustSliderThumbSize): + (WebCore::getMediaUIPartStateFlags): + (WebCore::getUnzoomedRectAndAdjustCurrentContext): + (WebCore::RenderThemeChromiumMac::paintMediaFullscreenButton): + (WebCore::RenderThemeChromiumMac::paintMediaMuteButton): + (WebCore::RenderThemeChromiumMac::paintMediaPlayButton): + (WebCore::RenderThemeChromiumMac::paintMediaSeekBackButton): + (WebCore::RenderThemeChromiumMac::paintMediaSeekForwardButton): + (WebCore::RenderThemeChromiumMac::paintMediaSliderTrack): + (WebCore::RenderThemeChromiumMac::paintMediaSliderThumb): + (WebCore::RenderThemeChromiumMac::paintMediaRewindButton): + (WebCore::RenderThemeChromiumMac::paintMediaReturnToRealtimeButton): + (WebCore::RenderThemeChromiumMac::paintMediaControlsBackground): + (WebCore::RenderThemeChromiumMac::paintMediaCurrentTime): + (WebCore::RenderThemeChromiumMac::paintMediaTimeRemaining): + (WebCore::RenderThemeChromiumMac::extraMediaControlsStyleSheet): + 2009-09-16 Daniel Bates <dbates@webkit.org> Reviewed by Darin Adler. diff --git a/src/3rdparty/webkit/WebCore/DerivedSources.cpp b/src/3rdparty/webkit/WebCore/DerivedSources.cpp index 408daba..2131793 100644 --- a/src/3rdparty/webkit/WebCore/DerivedSources.cpp +++ b/src/3rdparty/webkit/WebCore/DerivedSources.cpp @@ -333,7 +333,6 @@ #include "JSTreeWalker.cpp" #include "JSUIEvent.cpp" #include "JSValidityState.cpp" -#include "JSVoidCallback.cpp" #include "JSWebKitAnimationEvent.cpp" #include "JSWebKitCSSKeyframeRule.cpp" #include "JSWebKitCSSKeyframesRule.cpp" diff --git a/src/3rdparty/webkit/WebCore/WebCore.LP64.exp b/src/3rdparty/webkit/WebCore/WebCore.LP64.exp deleted file mode 100644 index cc04718..0000000 --- a/src/3rdparty/webkit/WebCore/WebCore.LP64.exp +++ /dev/null @@ -1,15 +0,0 @@ -# This file gets appended to WebCore.exp, only for 64-bit architectures. - -__ZN3JSC16RuntimeObjectImp6s_infoE -__ZN3JSC8Bindings10RootObjectD1Ev -__ZN3JSC8Bindings8Instance19createRuntimeObjectEPNS_9ExecStateE -__ZN3JSC8Bindings8InstanceC2EN3WTF10PassRefPtrINS0_10RootObjectEEE -__ZN3JSC8Bindings8InstanceD2Ev -__ZN7WebCore13IdentifierRep3getEi -__ZN7WebCore13IdentifierRep3getEPKc -__ZN7WebCore13IdentifierRep7isValidEPS0_ -__ZN7WebCore16ScriptController16createRootObjectEPv -__ZN7WebCore16ScriptController24jsObjectForPluginElementEPNS_17HTMLPlugInElementE -__ZN7WebCore16ScriptController9isEnabledEv -__ZN7WebCore6String26fromUTF8WithLatin1FallbackEPKcm -__ZN7WebCore6String8fromUTF8EPKcm diff --git a/src/3rdparty/webkit/WebCore/WebCore.gypi b/src/3rdparty/webkit/WebCore/WebCore.gypi index 3a5c73c..758d99d 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.gypi +++ b/src/3rdparty/webkit/WebCore/WebCore.gypi @@ -532,7 +532,6 @@ 'bindings/js/JSRGBColor.h', 'bindings/js/JSSharedWorkerConstructor.cpp', 'bindings/js/JSSharedWorkerConstructor.h', - 'bindings/js/JSSharedWorkerContextCustom.cpp', 'bindings/js/JSSharedWorkerCustom.cpp', 'bindings/js/JSSQLResultSetRowListCustom.cpp', 'bindings/js/JSSQLTransactionCustom.cpp', @@ -690,6 +689,8 @@ 'bindings/v8/custom/V8XMLSerializerConstructor.cpp', 'bindings/v8/custom/V8XPathEvaluatorConstructor.cpp', 'bindings/v8/custom/V8XSLTProcessorCustom.cpp', + 'bindings/v8/DateExtension.cpp', + 'bindings/v8/DateExtension.h', 'bindings/v8/DOMData.cpp', 'bindings/v8/DOMData.h', 'bindings/v8/DOMDataStore.cpp', @@ -1771,6 +1772,8 @@ 'platform/chromium/SuddenTerminationChromium.cpp', 'platform/chromium/SystemTimeChromium.cpp', 'platform/chromium/TemporaryLinkStubs.cpp', + 'platform/chromium/ThemeChromiumMac.h', + 'platform/chromium/ThemeChromiumMac.mm', 'platform/chromium/WidgetChromium.cpp', 'platform/chromium/WindowsVersion.cpp', 'platform/chromium/WindowsVersion.h', @@ -2064,6 +2067,7 @@ 'platform/graphics/FontFastPath.cpp', 'platform/graphics/FontRenderingMode.h', 'platform/graphics/FontSelector.h', + 'platform/graphics/FontSmoothingMode.h', 'platform/graphics/FontTraitsMask.h', 'platform/graphics/GeneratedImage.cpp', 'platform/graphics/GeneratedImage.h', diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index e614ffb..de3717d 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -169,8 +169,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) { } # Web Socket support. -# FIXME: Enable once platform code is landed. -# !contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=1 +!contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=1 DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1 @@ -714,7 +713,6 @@ SOURCES += \ bindings/js/JSInspectorCallbackWrapper.cpp \ bindings/js/JSLocationCustom.cpp \ bindings/js/JSNamedNodeMapCustom.cpp \ - bindings/js/JSNamedNodesCollection.cpp \ bindings/js/JSNavigatorCustom.cpp \ bindings/js/JSNodeCustom.cpp \ bindings/js/JSNodeFilterCondition.cpp \ @@ -1392,7 +1390,6 @@ HEADERS += \ bindings/js/JSLazyEventListener.h \ bindings/js/JSLocationCustom.h \ bindings/js/JSMessageChannelConstructor.h \ - bindings/js/JSNamedNodesCollection.h \ bindings/js/JSNodeFilterCondition.h \ bindings/js/JSOptionConstructor.h \ bindings/js/JSPluginElementFunctions.h \ @@ -1904,6 +1901,7 @@ HEADERS += \ platform/network/ResourceRequestBase.h \ platform/network/ResourceResponseBase.h \ platform/qt/ClipboardQt.h \ + platform/qt/QWebPageClient.h \ platform/qt/QWebPopup.h \ platform/qt/RenderThemeQt.h \ platform/qt/ScrollbarThemeQt.h \ @@ -2637,7 +2635,6 @@ contains(DEFINES, ENABLE_SHARED_WORKERS=1) { SOURCES += \ bindings/js/JSSharedWorkerConstructor.cpp \ - bindings/js/JSSharedWorkerContextCustom.cpp \ bindings/js/JSSharedWorkerCustom.cpp \ workers/DefaultSharedWorkerRepository.cpp \ workers/SharedWorker.cpp \ @@ -3105,6 +3102,20 @@ SOURCES += \ bindings/js/JSDOMApplicationCacheCustom.cpp } +contains(DEFINES, ENABLE_WEB_SOCKETS=1) { + FEATURE_DEFINES_JAVASCRIPT += ENABLE_WEB_SOCKETS=1 + +SOURCES += \ + websockets/WebSocket.cpp \ + websockets/WebSocketChannel.cpp \ + websockets/WebSocketHandshake.cpp \ + platform/network/SocketStreamErrorBase.cpp \ + platform/network/SocketStreamHandleBase.cpp \ + platform/network/qt/SocketStreamHandleSoup.cpp \ + bindings/js/JSWebSocketCustom.cpp \ + bindings/js/JSWebSocketConstructor.cpp +} + # GENERATOR 1: IDL compiler idl.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}JS${QMAKE_FILE_BASE}.cpp idl.variable_out = GENERATED_SOURCES diff --git a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityObject.h b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityObject.h index 8762fd8..c5ba1ed 100644 --- a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityObject.h +++ b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityObject.h @@ -316,6 +316,7 @@ public: virtual void linkedUIElements(AccessibilityChildrenVector&) const { } virtual AccessibilityObject* titleUIElement() const { return 0; } virtual bool exposesTitleUIElement() const { return true; } + virtual AccessibilityObject* correspondingControlForLabelElement() const { return 0; } virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; } virtual bool isPresentationalChildOfAriaRole() const { return false; } diff --git a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.cpp b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.cpp index b7dd601..834e931 100644 --- a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -1276,15 +1276,9 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const // find out if this element is inside of a label element. // if so, it may be ignored because it's the label for a checkbox or radio button - HTMLLabelElement* labelElement = labelElementContainer(); - if (labelElement) { - HTMLElement* correspondingControl = labelElement->correspondingControl(); - if (correspondingControl && correspondingControl->renderer()) { - AccessibilityObject* controlObject = axObjectCache()->getOrCreate(correspondingControl->renderer()); - if (!controlObject->exposesTitleUIElement()) - return true; - } - } + AccessibilityObject* controlObject = correspondingControlForLabelElement(); + if (controlObject && !controlObject->exposesTitleUIElement()) + return true; AccessibilityRole ariaRole = ariaRoleAttribute(); if (ariaRole == TextAreaRole || ariaRole == StaticTextRole) { @@ -2119,8 +2113,14 @@ AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const Int if (obj->isListBox()) return static_cast<AccessibilityListBox*>(result)->doAccessibilityHitTest(point); - if (result->accessibilityIsIgnored()) + if (result->accessibilityIsIgnored()) { + // If this element is the label of a control, a hit test should return the control. + AccessibilityObject* controlObject = result->correspondingControlForLabelElement(); + if (controlObject && !controlObject->exposesTitleUIElement()) + return controlObject; + result = result->parentObjectUnignored(); + } return result; } @@ -2199,6 +2199,18 @@ void AccessibilityRenderObject::handleActiveDescendantChanged() doc->axObjectCache()->postNotification(activedescendant->renderer(), AXObjectCache::AXFocusedUIElementChanged, true); } +AccessibilityObject* AccessibilityRenderObject::correspondingControlForLabelElement() const +{ + HTMLLabelElement* labelElement = labelElementContainer(); + if (!labelElement) + return 0; + + HTMLElement* correspondingControl = labelElement->correspondingControl(); + if (!correspondingControl) + return 0; + + return axObjectCache()->getOrCreate(correspondingControl->renderer()); +} AccessibilityObject* AccessibilityRenderObject::observableObject() const { @@ -2664,7 +2676,9 @@ void AccessibilityRenderObject::updateBackingStore() { if (!m_renderer) return; - m_renderer->view()->layoutIfNeeded(); -} - + + // Updating layout may delete m_renderer and this object. + m_renderer->document()->updateLayoutIgnorePendingStylesheets(); +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.h b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.h index e600b61..d82ca71 100644 --- a/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.h +++ b/src/3rdparty/webkit/WebCore/accessibility/AccessibilityRenderObject.h @@ -133,6 +133,8 @@ public: virtual void linkedUIElements(AccessibilityChildrenVector&) const; virtual bool exposesTitleUIElement() const; virtual AccessibilityObject* titleUIElement() const; + virtual AccessibilityObject* correspondingControlForLabelElement() const; + virtual AccessibilityRole ariaRoleAttribute() const; virtual bool isPresentationalChildOfAriaRole() const; virtual bool ariaRoleHasPresentationalChildren() const; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp index 475b374..aac1c63 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp @@ -44,21 +44,6 @@ using namespace JSC; namespace WebCore { -void JSAbstractWorker::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - - markIfNotNull(markStack, m_impl->onerror()); - - typedef AbstractWorker::EventListenersMap EventListenersMap; - typedef AbstractWorker::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } -} - JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index 4476be5..da4a53a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -49,13 +49,13 @@ PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(JSC::ExecSta setDOMException(exec, TYPE_MISMATCH_ERR); return 0; } - - return adoptRef(new JSCustomXPathNSResolver(resolverObject, asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame())); + + return adoptRef(new JSCustomXPathNSResolver(resolverObject, asJSDOMWindow(exec->dynamicGlobalObject()))); } -JSCustomXPathNSResolver::JSCustomXPathNSResolver(JSObject* customResolver, Frame* frame) +JSCustomXPathNSResolver::JSCustomXPathNSResolver(JSObject* customResolver, JSDOMWindow* globalObject) : m_customResolver(customResolver) - , m_frame(frame) + , m_globalObject(globalObject) { } @@ -67,15 +67,9 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { ASSERT(m_customResolver); - if (!m_frame) - return String(); - if (!m_frame->script()->isEnabled()) - return String(); - JSLock lock(SilenceAssertionsOnly); - JSGlobalObject* globalObject = m_frame->script()->globalObject(); - ExecState* exec = globalObject->globalExec(); + ExecState* exec = m_globalObject->globalExec(); JSValue function = m_customResolver->get(exec, Identifier(exec, "lookupNamespaceURI")); CallData callData; @@ -84,7 +78,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) callType = m_customResolver->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Pass actual line number and source URL. - m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String()); + m_globalObject->impl()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String()); return String(); } function = m_customResolver; @@ -95,9 +89,9 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) MarkedArgumentBuffer args; args.append(jsString(exec, prefix)); - globalObject->globalData()->timeoutChecker.start(); + m_globalObject->globalData()->timeoutChecker.start(); JSValue retval = call(exec, function, callType, callData, m_customResolver, args); - globalObject->globalData()->timeoutChecker.stop(); + m_globalObject->globalData()->timeoutChecker.stop(); String result; if (exec->hadException()) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.h b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.h index 44c44f9..7d66494 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.h @@ -41,6 +41,7 @@ namespace JSC { namespace WebCore { class Frame; + class JSDOMWindow; class JSCustomXPathNSResolver : public XPathNSResolver { public: @@ -51,10 +52,11 @@ namespace WebCore { virtual String lookupNamespaceURI(const String& prefix); private: - JSCustomXPathNSResolver(JSC::JSObject*, Frame*); + JSCustomXPathNSResolver(JSC::JSObject*, JSDOMWindow*); - JSC::JSObject* m_customResolver; // JSCustomXPathNSResolvers are always temporary, thus no need to GC protect the object. - RefPtr<Frame> m_frame; + // JSCustomXPathNSResolvers are always temporary, thus no need to GC protect the objects. + JSC::JSObject* m_customResolver; + JSDOMWindow* m_globalObject; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index b833e71..5855026 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp @@ -42,28 +42,6 @@ using namespace JSC; namespace WebCore { -void JSDOMApplicationCache::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - - markIfNotNull(markStack, m_impl->onchecking()); - markIfNotNull(markStack, m_impl->onerror()); - markIfNotNull(markStack, m_impl->onnoupdate()); - markIfNotNull(markStack, m_impl->ondownloading()); - markIfNotNull(markStack, m_impl->onprogress()); - markIfNotNull(markStack, m_impl->onupdateready()); - markIfNotNull(markStack, m_impl->oncached()); - markIfNotNull(markStack, m_impl->onobsolete()); - - typedef DOMApplicationCache::EventListenersMap EventListenersMap; - typedef DOMApplicationCache::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } -} - #if ENABLE(APPLICATION_CACHE_DYNAMIC_ENTRIES) JSValue JSDOMApplicationCache::hasItem(ExecState* exec, const ArgList& args) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp index df384ea..1899797 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp @@ -275,7 +275,7 @@ static inline bool isObservableThroughDOM(JSNode* jsNode) // If a node is in the document, and has event listeners, its wrapper is // observable because its wrapper is responsible for marking those event listeners. - if (node->eventListeners().size()) + if (node->hasEventListeners()) return true; // Technically, we may overzealously mark a wrapper for a node that has only non-JS event listeners. Oh well. // If a node owns another object with a wrapper with custom properties, @@ -323,6 +323,11 @@ static inline bool isObservableThroughDOM(JSNode* jsNode) #endif } + // If a node is firing event listeners, its wrapper is observable because + // its wrapper is responsible for marking those event listeners. + if (node->isFiringEventListeners()) + return true; + return false; } @@ -648,4 +653,10 @@ JSC::JSObject* toJSSequence(ExecState* exec, JSValue value, unsigned& length) return object; } +bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool) +{ + throwError(exec, TypeError, "defineProperty is not supported on DOM Objects"); + return false; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h index c3ab266..c46513c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h @@ -55,6 +55,8 @@ namespace WebCore { { } + virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool); + #ifndef NDEBUG virtual ~DOMObject(); #endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp index 27e95fe..08c7144 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -94,7 +94,7 @@ void JSDOMWindow::markChildren(MarkStack& markStack) { Base::markChildren(markStack); - markEventListeners(markStack, impl()->eventListeners()); + impl()->markEventListeners(markStack); JSGlobalData& globalData = *Heap::heap(this)->globalData(); @@ -488,7 +488,7 @@ bool JSDOMWindow::getPropertyAttributes(ExecState* exec, const Identifier& prope return Base::getPropertyAttributes(exec, propertyName, attributes); } -void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { // Only allow defining getters by frames in the same origin. if (!allowsAccessFrom(exec)) @@ -498,15 +498,23 @@ void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, if (propertyName == "location") return; - Base::defineGetter(exec, propertyName, getterFunction); + Base::defineGetter(exec, propertyName, getterFunction, attributes); } -void JSDOMWindow::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void JSDOMWindow::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { // Only allow defining setters by frames in the same origin. if (!allowsAccessFrom(exec)) return; - Base::defineSetter(exec, propertyName, setterFunction); + Base::defineSetter(exec, propertyName, setterFunction, attributes); +} + +bool JSDOMWindow::defineOwnProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow) +{ + // Only allow defining properties in this way by frames in the same origin, as it allows setters to be introduced. + if (!allowsAccessFrom(exec)) + return false; + return Base::defineOwnProperty(exec, propertyName, descriptor, shouldThrow); } JSValue JSDOMWindow::lookupGetter(ExecState* exec, const Identifier& propertyName) @@ -572,13 +580,13 @@ void JSDOMWindow::setLocation(ExecState* exec, JSValue value) Frame* frame = impl()->frame(); ASSERT(frame); - if (!shouldAllowNavigation(exec, frame)) - return; - KURL url = completeURL(exec, value.toString(exec)); if (url.isNull()) return; + if (!shouldAllowNavigation(exec, frame)) + return; + if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) { // We want a new history item if this JS was called via a user gesture frame->loader()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture(exec)); @@ -773,6 +781,10 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) { + String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(1).toString(exec)); + WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(2))); + Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); @@ -785,9 +797,6 @@ JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) Page* page = frame->page(); - String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); - AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(1).toString(exec)); - // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. if (!DOMWindow::allowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName))) @@ -805,13 +814,13 @@ JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) topOrParent = true; } if (topOrParent) { - if (!shouldAllowNavigation(exec, frame)) - return jsUndefined(); - String completedURL; if (!urlString.isEmpty()) completedURL = completeURL(exec, urlString).string(); + if (!shouldAllowNavigation(exec, frame)) + return jsUndefined(); + const JSDOMWindow* targetedWindow = toJSDOMWindow(frame); if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { bool userGesture = processingUserGesture(exec); @@ -827,7 +836,6 @@ JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) } // In the case of a named frame or a new window, we'll use the createWindow() helper - WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(2))); FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect); @@ -847,6 +855,10 @@ JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) JSValue JSDOMWindow::showModalDialog(ExecState* exec, const ArgList& args) { + String url = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + JSValue dialogArgs = args.at(1); + String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); @@ -860,10 +872,6 @@ JSValue JSDOMWindow::showModalDialog(ExecState* exec, const ArgList& args) if (!DOMWindow::canShowModalDialogNow(frame) || !DOMWindow::allowPopUp(dynamicFrame)) return jsUndefined(); - String url = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); - JSValue dialogArgs = args.at(1); - String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); - HashMap<String, String> features; DOMWindow::parseModalDialogFeatures(featureArgs, features); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp index f969dc1..3c3ff4c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -103,6 +103,11 @@ void JSDOMWindowShell::putWithAttributes(ExecState* exec, const Identifier& prop m_window->putWithAttributes(exec, propertyName, value, attributes); } +bool JSDOMWindowShell::defineOwnProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow) +{ + return m_window->defineOwnProperty(exec, propertyName, descriptor, shouldThrow); +} + bool JSDOMWindowShell::deleteProperty(ExecState* exec, const Identifier& propertyName) { return m_window->deleteProperty(exec, propertyName); @@ -123,14 +128,14 @@ bool JSDOMWindowShell::getPropertyAttributes(JSC::ExecState* exec, const Identif return m_window->getPropertyAttributes(exec, propertyName, attributes); } -void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { - m_window->defineGetter(exec, propertyName, getterFunction); + m_window->defineGetter(exec, propertyName, getterFunction, attributes); } -void JSDOMWindowShell::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) +void JSDOMWindowShell::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) { - m_window->defineSetter(exec, propertyName, setterFunction); + m_window->defineSetter(exec, propertyName, setterFunction, attributes); } JSValue JSDOMWindowShell::lookupGetter(ExecState* exec, const Identifier& propertyName) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h index a7c2c56..23af340 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h @@ -74,8 +74,9 @@ namespace WebCore { virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const; - virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); - virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes); + virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); virtual JSC::JSObject* unwrappedObject(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp index a633a42..fbee5ef 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp @@ -42,13 +42,6 @@ using namespace JSC; namespace WebCore { -void JSDedicatedWorkerContext::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - - markIfNotNull(markStack, impl()->onmessage()); -} - JSC::JSValue JSDedicatedWorkerContext::postMessage(JSC::ExecState* exec, const JSC::ArgList& args) { return handlePostMessage(exec, args, impl()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp index d391073..48ae014 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp @@ -56,7 +56,7 @@ void JSEventListener::markJSFunction(MarkStack& markStack) markStack.append(m_globalObject); } -void JSEventListener::handleEvent(Event* event, bool isWindowEvent) +void JSEventListener::handleEvent(Event* event) { JSLock lock(SilenceAssertionsOnly); @@ -106,19 +106,10 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent) JSGlobalData* globalData = globalObject->globalData(); DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject); - JSValue retval; - if (handleEventFunction) { - globalData->timeoutChecker.start(); - retval = call(exec, handleEventFunction, callType, callData, jsFunction, args); - } else { - JSValue thisValue; - if (isWindowEvent) - thisValue = globalObject->toThisObject(exec); - else - thisValue = toJS(exec, globalObject, event->currentTarget()); - globalData->timeoutChecker.start(); - retval = call(exec, jsFunction, callType, callData, thisValue, args); - } + globalData->timeoutChecker.start(); + JSValue retval = handleEventFunction + ? call(exec, handleEventFunction, callType, callData, jsFunction, args) + : call(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args); globalData->timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h index 92f0c41..91ceff7 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h @@ -53,7 +53,7 @@ namespace WebCore { private: virtual void markJSFunction(JSC::MarkStack&); - virtual void handleEvent(Event*, bool isWindowEvent); + virtual void handleEvent(Event*); virtual bool reportError(const String& message, const String& url, int lineNumber); virtual bool virtualisAttribute() const; void clearJSFunctionInline(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp index deebcb9..d757ef6 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp @@ -43,23 +43,6 @@ using namespace JSC; namespace WebCore { -void JSEventSource::markChildren(MarkStack& markStack) -{ - DOMObject::markChildren(markStack); - - markIfNotNull(markStack, m_impl->onopen()); - markIfNotNull(markStack, m_impl->onmessage()); - markIfNotNull(markStack, m_impl->onerror()); - - typedef EventSource::EventListenersMap EventListenersMap; - typedef EventSource::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } -} - JSValue JSEventSource::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp index 10f8bd5..530b89b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp @@ -100,20 +100,34 @@ static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValu if (exec->hadException()) return 0; if (!timeoutValue.isUndefined()) { - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setTimeout(max(0, timeoutValue.toInt32(exec))); + double timeoutNumber = timeoutValue.toNumber(exec); if (exec->hadException()) return 0; + // If the value is positive infinity, there's nothing to do. + if (!(isinf(timeoutNumber) && (timeoutNumber > 0))) { + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setTimeout(max(0, timeoutValue.toInt32(exec))); + if (exec->hadException()) + return 0; + } } JSValue maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge")); if (exec->hadException()) return 0; if (!maximumAgeValue.isUndefined()) { - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setMaximumAge(max(0, maximumAgeValue.toInt32(exec))); + double maximumAgeNumber = maximumAgeValue.toNumber(exec); if (exec->hadException()) return 0; + if (isinf(maximumAgeNumber) && (maximumAgeNumber > 0)) { + // If the value is positive infinity, clear maximumAge. + options->clearMaximumAge(); + } else { + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setMaximumAge(max(0, maximumAgeValue.toInt32(exec))); + if (exec->hadException()) + return 0; + } } return options.release(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp index dd9af74..8ffddf7 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -23,12 +23,13 @@ #include "AtomicString.h" #include "HTMLCollection.h" #include "HTMLOptionsCollection.h" +#include "JSDOMBinding.h" #include "JSHTMLAllCollection.h" #include "JSHTMLOptionsCollection.h" -#include "JSNamedNodesCollection.h" #include "JSNode.h" +#include "JSNodeList.h" #include "Node.h" -#include "JSDOMBinding.h" +#include "StaticNodeList.h" #include <wtf/Vector.h> using namespace JSC; @@ -42,11 +43,13 @@ static JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, cons if (namedItems.isEmpty()) return jsUndefined(); - if (namedItems.size() == 1) return toJS(exec, collection->globalObject(), namedItems[0].get()); - return new (exec) JSNamedNodesCollection(exec, collection->globalObject(), namedItems); + // FIXME: HTML5 specifies that this should be a DynamicNodeList. + // FIXME: HTML5 specifies that non-HTMLOptionsCollection collections should return + // the first matching item instead of a NodeList. + return toJS(exec, collection->globalObject(), StaticNodeList::adopt(namedItems).get()); } // HTMLCollections are strange objects, they support both get and call, diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp index ffa2d57..de9ec4a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -30,7 +30,8 @@ #include "HTMLCollection.h" #include "HTMLFormElement.h" #include "JSDOMWindowCustom.h" -#include "JSNamedNodesCollection.h" +#include "JSNodeList.h" +#include "StaticNodeList.h" using namespace JSC; @@ -47,15 +48,17 @@ JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propert { JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slot.slotBase())); HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl()); - + Vector<RefPtr<Node> > namedItems; form->getNamedElements(propertyName, namedItems); + if (namedItems.isEmpty()) + return jsUndefined(); if (namedItems.size() == 1) return toJS(exec, namedItems[0].get()); - if (namedItems.size() > 1) - return new (exec) JSNamedNodesCollection(exec, jsForm->globalObject(), namedItems); - return jsUndefined(); + + // FIXME: HTML5 specifies that this should be a RadioNodeList. + return toJS(exec, jsForm->globalObject(), StaticNodeList::adopt(namedItems).get()); } JSValue JSHTMLFormElement::submit(ExecState* exec, const ArgList&) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp index ef58349..aecec5e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp @@ -182,11 +182,11 @@ void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propert Base::getOwnPropertyNames(exec, propertyNames); } -void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) return; - Base::defineGetter(exec, propertyName, getterFunction); + Base::defineGetter(exec, propertyName, getterFunction, attributes); } static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) @@ -204,13 +204,13 @@ void JSLocation::setHref(ExecState* exec, JSValue value) Frame* frame = impl()->frame(); ASSERT(frame); - if (!shouldAllowNavigation(exec, frame)) - return; - KURL url = completeURL(exec, value.toString(exec)); if (url.isNull()) return; + if (!shouldAllowNavigation(exec, frame)) + return; + navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } @@ -308,13 +308,13 @@ JSValue JSLocation::replace(ExecState* exec, const ArgList& args) if (!frame) return jsUndefined(); - if (!shouldAllowNavigation(exec, frame)) - return jsUndefined(); - KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); + if (!shouldAllowNavigation(exec, frame)) + return jsUndefined(); + navigateIfAllowed(exec, frame, url, true, true); return jsUndefined(); } @@ -336,13 +336,13 @@ JSValue JSLocation::assign(ExecState* exec, const ArgList& args) if (!frame) return jsUndefined(); - if (!shouldAllowNavigation(exec, frame)) - return jsUndefined(); - KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); + if (!shouldAllowNavigation(exec, frame)) + return jsUndefined(); + // We want a new history item if this JS was called via a user gesture navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); return jsUndefined(); @@ -362,11 +362,11 @@ bool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propert return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf); } -void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) return; - Base::defineGetter(exec, propertyName, getterFunction); + Base::defineGetter(exec, propertyName, getterFunction, attributes); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp index 8202d1a..2084905 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp @@ -45,8 +45,6 @@ void JSMessagePort::markChildren(MarkStack& markStack) { Base::markChildren(markStack); - markIfNotNull(markStack, m_impl->onmessage()); - // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext(). if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort); @@ -54,13 +52,7 @@ void JSMessagePort::markChildren(MarkStack& markStack) markStack.append(wrapper); } - typedef MessagePort::EventListenersMap EventListenersMap; - typedef MessagePort::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } + m_impl->markEventListeners(markStack); } JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.cpp deleted file mode 100644 index a1cb202..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE 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. - */ - -#include "config.h" -#include "JSNamedNodesCollection.h" - -#include "AtomicString.h" -#include "Element.h" -#include "JSNode.h" -#include "NamedNodeMap.h" - -namespace WebCore { - -using namespace JSC; - -ASSERT_CLASS_FITS_IN_CELL(JSNamedNodesCollection); - -const ClassInfo JSNamedNodesCollection::s_info = { "Collection", 0, 0, 0 }; - -// Such a collection is usually very short-lived, it only exists -// for constructs like document.forms.<name>[1], -// so it shouldn't be a problem that it's storing all the nodes (with the same name). (David) -JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<RefPtr<Node> >& nodes) - : DOMObjectWithGlobalPointer(getDOMStructure<JSNamedNodesCollection>(exec, globalObject), globalObject) - , m_nodes(new Vector<RefPtr<Node> >(nodes)) -{ -} - -JSValue JSNamedNodesCollection::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - JSNamedNodesCollection* thisObj = static_cast<JSNamedNodesCollection*>(asObject(slot.slotBase())); - return jsNumber(exec, thisObj->m_nodes->size()); -} - -JSValue JSNamedNodesCollection::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - JSNamedNodesCollection *thisObj = static_cast<JSNamedNodesCollection*>(asObject(slot.slotBase())); - return toJS(exec, (*thisObj->m_nodes)[slot.index()].get()); -} - -bool JSNamedNodesCollection::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (propertyName == exec->propertyNames().length) { - slot.setCustom(this, lengthGetter); - return true; - } - - bool ok; - unsigned index = propertyName.toUInt32(&ok); - if (ok && index < m_nodes->size()) { - slot.setCustomIndex(this, index, indexGetter); - return true; - } - - // For IE compatibility, we need to be able to look up elements in a - // document.formName.name result by id as well as be index. - - AtomicString atomicPropertyName = propertyName; - for (unsigned i = 0; i < m_nodes->size(); i++) { - Node* node = (*m_nodes)[i].get(); - if (node->hasAttributes() && node->attributes()->id() == atomicPropertyName) { - slot.setCustomIndex(this, i, indexGetter); - return true; - } - } - - return DOMObjectWithGlobalPointer::getOwnPropertySlot(exec, propertyName, slot); -} - -bool JSNamedNodesCollection::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (propertyName == exec->propertyNames().length) { - descriptor.setDescriptor(jsNumber(exec, m_nodes->size()), ReadOnly | DontDelete | DontEnum); - return true; - } - - bool ok; - unsigned index = propertyName.toUInt32(&ok); - if (ok && index < m_nodes->size()) { - PropertySlot slot; - slot.setCustomIndex(this, index, indexGetter); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete); - return true; - } - - // For IE compatibility, we need to be able to look up elements in a - // document.formName.name result by id as well as be index. - - AtomicString atomicPropertyName = propertyName; - for (unsigned i = 0; i < m_nodes->size(); i++) { - Node* node = (*m_nodes)[i].get(); - if (node->hasAttributes() && node->attributes()->id() == atomicPropertyName) { - PropertySlot slot; - slot.setCustomIndex(this, i, indexGetter); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete); - return true; - } - } - - return DOMObjectWithGlobalPointer::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.h b/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.h deleted file mode 100644 index fc629d8..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodesCollection.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE 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 JSNamedNodesCollection_h -#define JSNamedNodesCollection_h - -#include "JSDOMBinding.h" -#include <wtf/Vector.h> - -namespace WebCore { - - class Node; - - // Internal class, used for the collection return by e.g. document.forms.myinput - // when multiple nodes have the same name. - class JSNamedNodesCollection : public DOMObjectWithGlobalPointer { - public: - JSNamedNodesCollection(JSC::ExecState*, JSDOMGlobalObject*, const Vector<RefPtr<Node> >&); - - virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); - - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - static const JSC::ClassInfo s_info; - - static JSC::ObjectPrototype* createPrototype(JSC::ExecState*, JSC::JSGlobalObject* globalObject) - { - return globalObject->objectPrototype(); - } - - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) - { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); - } - - private: - static JSC::JSValue lengthGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - - OwnPtr<Vector<RefPtr<Node> > > m_nodes; - }; - -} // namespace WebCore - -#endif // JSNamedNodesCollection_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp index e88a9ec..025a8fa 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp @@ -150,10 +150,10 @@ void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const void JSNode::markChildren(MarkStack& markStack) { - Node* node = m_impl.get(); - Base::markChildren(markStack); - markEventListeners(markStack, node->eventListeners()); + + Node* node = m_impl.get(); + node->markEventListeners(markStack); // Nodes in the document are kept alive by JSDocument::mark, so, if we're in // the document, we need to mark the document, but we don't need to explicitly diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp index a071a4e..30acf9b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp @@ -148,7 +148,7 @@ bool JSQuarantinedObjectWrapper::getOwnPropertyDescriptor(ExecState* exec, const PropertyDescriptor unwrappedDescriptor; bool result = m_unwrappedObject->getOwnPropertyDescriptor(unwrappedExecState(), identifier, unwrappedDescriptor); - if (unwrappedDescriptor.hasAccessors()) { + if (unwrappedDescriptor.isAccessorDescriptor()) { descriptor.setAccessorDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.getter()), wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.setter()), unwrappedDescriptor.attributes()); @@ -178,6 +178,33 @@ void JSQuarantinedObjectWrapper::put(ExecState* exec, unsigned identifier, JSVal transferExceptionToExecState(exec); } +bool JSQuarantinedObjectWrapper::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow) +{ + if (!allowsSetProperty()) + return false; + + PropertyDescriptor wrappedDescriptor; + if (descriptor.isDataDescriptor()) { + wrappedDescriptor.setValue(prepareIncomingValue(exec, descriptor.value())); + if (wrappedDescriptor.writablePresent()) + wrappedDescriptor.setWritable(descriptor.writable()); + } else if (descriptor.isAccessorDescriptor()) { + if (descriptor.getter()) + wrappedDescriptor.setGetter(prepareIncomingValue(exec, descriptor.getter())); + if (descriptor.setter()) + wrappedDescriptor.setSetter(prepareIncomingValue(exec, descriptor.setter())); + } + if (wrappedDescriptor.enumerablePresent()) + wrappedDescriptor.setEnumerable(descriptor.enumerable()); + if (wrappedDescriptor.configurablePresent()) + wrappedDescriptor.setConfigurable(descriptor.configurable()); + + bool result = m_unwrappedObject->defineOwnProperty(unwrappedExecState(), propertyName, wrappedDescriptor, shouldThrow); + + transferExceptionToExecState(exec); + return result; +} + bool JSQuarantinedObjectWrapper::deleteProperty(ExecState* exec, const Identifier& identifier) { if (!allowsDeleteProperty()) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h index 37f2518..2bc6633 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h @@ -62,6 +62,7 @@ namespace WebCore { virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); virtual void put(JSC::ExecState*, unsigned, JSC::JSValue); + virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); virtual bool deleteProperty(JSC::ExecState*, unsigned); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.cpp index 651805c..c05b3d2 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.cpp @@ -57,11 +57,14 @@ static JSObject* constructSharedWorker(ExecState* exec, JSObject* constructor, c { JSSharedWorkerConstructor* jsConstructor = static_cast<JSSharedWorkerConstructor*>(constructor); - if (args.size() < 2) + if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); UString scriptURL = args.at(0).toString(exec); - UString name = args.at(1).toString(exec); + UString name; + if (args.size() > 1) + name = args.at(1).toString(exec); + if (exec->hadException()) return 0; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp index 401b33d..d305502 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp @@ -44,14 +44,6 @@ using namespace JSC; namespace WebCore { -void JSWebSocket::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - if (m_impl->readyState() != WebSocket::CLOSED) - markIfNotNull(markStack, m_impl->onmessage()); - // FIXME: mark if EventListeners is registered. -} - // Custom functions JSValue JSWebSocket::send(ExecState* exec, const ArgList& args) { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp index 9e54fa0..1b78264 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -62,15 +62,7 @@ void JSWorkerContext::markChildren(MarkStack& markStack) markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation()); markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator()); - markIfNotNull(markStack, impl()->onerror()); - - typedef WorkerContext::EventListenersMap EventListenersMap; - typedef WorkerContext::ListenerVector ListenerVector; - EventListenersMap& eventListeners = impl()->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } + impl()->markEventListeners(markStack); } bool JSWorkerContext::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerCustom.cpp index a42a043..09b881a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerCustom.cpp @@ -37,13 +37,6 @@ using namespace JSC; namespace WebCore { -void JSWorker::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - - markIfNotNull(markStack, static_cast<Worker*>(impl())->onmessage()); -} - JSC::JSValue JSWorker::postMessage(JSC::ExecState* exec, const JSC::ArgList& args) { return handlePostMessage(exec, args, impl()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index c69f727..6d0ce57 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -59,20 +59,7 @@ void JSXMLHttpRequest::markChildren(MarkStack& markStack) markStack.append(wrapper); } - markIfNotNull(markStack, m_impl->onreadystatechange()); - markIfNotNull(markStack, m_impl->onabort()); - markIfNotNull(markStack, m_impl->onerror()); - markIfNotNull(markStack, m_impl->onload()); - markIfNotNull(markStack, m_impl->onloadstart()); - markIfNotNull(markStack, m_impl->onprogress()); - - typedef XMLHttpRequest::EventListenersMap EventListenersMap; - typedef XMLHttpRequest::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } + m_impl->markEventListeners(markStack); } // Custom functions diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index 2f17542..c0f0c39 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp @@ -51,19 +51,7 @@ void JSXMLHttpRequestUpload::markChildren(MarkStack& markStack) markStack.append(wrapper); } - markIfNotNull(markStack, m_impl->onabort()); - markIfNotNull(markStack, m_impl->onerror()); - markIfNotNull(markStack, m_impl->onload()); - markIfNotNull(markStack, m_impl->onloadstart()); - markIfNotNull(markStack, m_impl->onprogress()); - - typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap; - typedef XMLHttpRequestUpload::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(markStack); - } + m_impl->markEventListeners(markStack); } JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp index 4b33069..dfa1602 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp @@ -85,12 +85,7 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); String sourceURL = jsSourceCode.provider()->url(); - if (sourceURL.isNull() && !m_XSSAuditor->canEvaluateJavaScriptURL(sourceCode.source())) { - // This JavaScript URL is not safe to be evaluated. - return JSValue(); - } - - if (!sourceURL.isNull() && !m_XSSAuditor->canEvaluate(sourceCode.source())) { + if (!m_XSSAuditor->canEvaluate(sourceCode.source())) { // This script is not safe to be evaluated. return JSValue(); } diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm index 88f67f0..3523b43 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -476,7 +476,9 @@ sub GenerateHeader my $parentClassName = GetParentClassName($dataNode); my $conditional = $dataNode->extendedAttributes->{"Conditional"}; my $needsSVGContext = IsSVGTypeNeedingContextParameter($interfaceName); - + my $eventTarget = $dataNode->extendedAttributes->{"EventTarget"}; + my $needsMarkChildren = $dataNode->extendedAttributes->{"CustomMarkFunction"} || $dataNode->extendedAttributes->{"EventTarget"}; + # - Add default header template @headerContentHeader = split("\r", $headerTemplate); @@ -548,7 +550,7 @@ sub GenerateHeader } # Destructor - push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document" or $interfaceName eq "DOMWindow"); + push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $eventTarget or $interfaceName eq "Document" or $interfaceName eq "DOMWindow"); # Prototype push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}); @@ -613,8 +615,8 @@ sub GenerateHeader " }\n\n"); } - # Custom mark function - push(@headerContent, " virtual void markChildren(JSC::MarkStack&);\n\n") if $dataNode->extendedAttributes->{"CustomMarkFunction"}; + # markChildren function + push(@headerContent, " virtual void markChildren(JSC::MarkStack&);\n\n") if $needsMarkChildren; # Custom pushEventHandlerScope function push(@headerContent, " virtual void pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChain&) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"}; @@ -627,6 +629,10 @@ sub GenerateHeader # Custom getPropertyNames function exists on DOMWindow push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if $interfaceName eq "DOMWindow"; + + # Custom defineProperty function exists on DOMWindow + push(@headerContent, " virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow);\n") if $interfaceName eq "DOMWindow"; + # Custom getOwnPropertyNames function push(@headerContent, " virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}); @@ -634,10 +640,10 @@ sub GenerateHeader push(@headerContent, " virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const;\n") if $dataNode->extendedAttributes->{"CustomGetPropertyAttributes"}; # Custom defineGetter function - push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction);\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"}; + push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"}; # Custom defineSetter function - push(@headerContent, " virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction);\n") if $dataNode->extendedAttributes->{"CustomDefineSetter"}; + push(@headerContent, " virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineSetter"}; # Custom lookupGetter function push(@headerContent, " virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupGetter"}; @@ -785,7 +791,7 @@ sub GenerateHeader push(@headerContent, " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . - " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType" . ($dataNode->extendedAttributes->{"CustomMarkFunction"} ? "" : ", JSC::HasDefaultMark") . "));\n" . + " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType" . ($needsMarkChildren ? "" : ", JSC::HasDefaultMark") . "));\n" . " }\n"); } elsif ($dataNode->extendedAttributes->{"CustomMarkFunction"}) { push(@headerContent, @@ -800,7 +806,7 @@ sub GenerateHeader } # Custom defineGetter function - push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction);\n") if $dataNode->extendedAttributes->{"CustomPrototypeDefineGetter"}; + push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomPrototypeDefineGetter"}; push(@headerContent, " ${className}Prototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { }\n"); @@ -864,6 +870,8 @@ sub GenerateImplementation my $parentClassName = GetParentClassName($dataNode); my $conditional = $dataNode->extendedAttributes->{"Conditional"}; my $visibleClassName = GetVisibleClassName($interfaceName); + my $eventTarget = $dataNode->extendedAttributes->{"EventTarget"}; + my $needsMarkChildren = $dataNode->extendedAttributes->{"CustomMarkFunction"} || $dataNode->extendedAttributes->{"EventTarget"}; # - Add default header template @implContentHeader = split("\r", $headerTemplate); @@ -1149,17 +1157,17 @@ sub GenerateImplementation push(@implContent, "}\n\n"); # Destructor - if (!$hasParent || $interfaceName eq "DOMWindow") { + if (!$hasParent || $eventTarget) { push(@implContent, "${className}::~$className()\n"); push(@implContent, "{\n"); + if ($eventTarget) { + $implIncludes{"RegisteredEventListener.h"} = 1; + push(@implContent, " impl()->invalidateEventListeners();\n"); + } + if ($interfaceName eq "Node") { - $implIncludes{"RegisteredEventListener.h"} = 1; - push(@implContent, " invalidateEventListeners(m_impl->eventListeners());\n"); - push(@implContent, " forgetDOMNode(m_impl->document(), m_impl.get());\n"); - } elsif ($interfaceName eq "DOMWindow") { - $implIncludes{"RegisteredEventListener.h"} = 1; - push(@implContent, " invalidateEventListeners(impl()->eventListeners());\n"); + push(@implContent, " forgetDOMNode(impl()->document(), impl());\n"); } else { if ($podType) { my $animatedType = $implClassName; @@ -1170,7 +1178,7 @@ sub GenerateImplementation push(@implContent, " JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n"); } } - push(@implContent, " forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get());\n"); + push(@implContent, " forgetDOMObject(*Heap::heap(this)->globalData(), impl());\n"); } push(@implContent, "}\n\n"); @@ -1183,6 +1191,14 @@ sub GenerateImplementation push(@implContent, "{\n forgetDOMObject(*Heap::heap(this)->globalData(), static_cast<${implClassName}*>(impl()));\n}\n\n"); } + if ($needsMarkChildren && !$dataNode->extendedAttributes->{"CustomMarkFunction"}) { + push(@implContent, "void ${className}::markChildren(MarkStack& markStack)\n"); + push(@implContent, "{\n"); + push(@implContent, " Base::markChildren(markStack);\n"); + push(@implContent, " impl()->markEventListeners(markStack);\n"); + push(@implContent, "}\n\n"); + } + if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec, JSGlobalObject* globalObject)\n"); push(@implContent, "{\n"); diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm index b3307cd..a18de49 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -1003,7 +1003,12 @@ sub GenerateBatchedAttributeData # Replaceable if ($attrExt->{"Replaceable"} && !$hasCustomSetter) { $setter = "0"; - $propAttr .= "|v8::ReadOnly"; + # Handle the special case of window.top being marked as Replaceable. + # FIXME: Investigate whether we could treat window.top as replaceable + # and allow shadowing without it being a security hole. + if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) { + $propAttr .= "|v8::ReadOnly"; + } } # Read only attributes diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp index 58280e3..0546014 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp @@ -43,16 +43,10 @@ namespace Bindings { typedef QMultiHash<void*, QtInstance*> QObjectInstanceMap; static QObjectInstanceMap cachedInstances; -// Cache JSObjects -typedef QHash<QtInstance*, JSObject*> InstanceJSObjectMap; -static InstanceJSObjectMap cachedObjects; - // Derived RuntimeObject class QtRuntimeObjectImp : public RuntimeObjectImp { public: QtRuntimeObjectImp(ExecState*, PassRefPtr<Instance>); - ~QtRuntimeObjectImp(); - virtual void invalidate(); static const ClassInfo s_info; @@ -64,9 +58,6 @@ public: instance->markAggregate(markStack); } -protected: - void removeFromCache(); - private: virtual const ClassInfo* classInfo() const { return &s_info; } }; @@ -78,25 +69,6 @@ QtRuntimeObjectImp::QtRuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> ins { } -QtRuntimeObjectImp::~QtRuntimeObjectImp() -{ - removeFromCache(); -} - -void QtRuntimeObjectImp::invalidate() -{ - removeFromCache(); - RuntimeObjectImp::invalidate(); -} - -void QtRuntimeObjectImp::removeFromCache() -{ - JSLock lock(SilenceAssertionsOnly); - QtInstance* key = cachedObjects.key(this); - if (key) - cachedObjects.remove(key); -} - // QtInstance QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership) : Instance(rootObject) @@ -112,7 +84,6 @@ QtInstance::~QtInstance() { JSLock lock(SilenceAssertionsOnly); - cachedObjects.remove(this); cachedInstances.remove(m_hashkey); // clean up (unprotect from gc) the JSValues we've created @@ -190,16 +161,10 @@ Class* QtInstance::getClass() const return m_class; } -RuntimeObjectImp* QtInstance::createRuntimeObject(ExecState* exec) +RuntimeObjectImp* QtInstance::newRuntimeObject(ExecState* exec) { JSLock lock(SilenceAssertionsOnly); - RuntimeObjectImp* ret = static_cast<RuntimeObjectImp*>(cachedObjects.value(this)); - if (!ret) { - ret = new (exec) QtRuntimeObjectImp(exec, this); - cachedObjects.insert(this, ret); - ret = static_cast<RuntimeObjectImp*>(cachedObjects.value(this)); - } - return ret; + return new (exec) QtRuntimeObjectImp(exec, this); } void QtInstance::markAggregate(MarkStack& markStack) diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h index c276b29..00aaa5b 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h @@ -40,7 +40,7 @@ public: ~QtInstance(); virtual Class* getClass() const; - virtual RuntimeObjectImp* createRuntimeObject(ExecState*); + virtual RuntimeObjectImp* newRuntimeObject(ExecState*); virtual void begin(); virtual void end(); diff --git a/src/3rdparty/webkit/WebCore/bridge/runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/runtime.cpp index 6934406..eac8586 100644 --- a/src/3rdparty/webkit/WebCore/bridge/runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/runtime.cpp @@ -48,12 +48,14 @@ Array::~Array() Instance::Instance(PassRefPtr<RootObject> rootObject) : _rootObject(rootObject) + , m_runtimeObject(0) { ASSERT(_rootObject); } Instance::~Instance() { + ASSERT(!m_runtimeObject); } static KJSDidExecuteFunctionPtr s_didExecuteFunction; @@ -80,11 +82,37 @@ void Instance::end() RuntimeObjectImp* Instance::createRuntimeObject(ExecState* exec) { + ASSERT(_rootObject); + ASSERT(_rootObject->isValid()); + if (m_runtimeObject) + return m_runtimeObject; + JSLock lock(SilenceAssertionsOnly); + m_runtimeObject = newRuntimeObject(exec); + _rootObject->addRuntimeObject(m_runtimeObject); + return m_runtimeObject; +} + +RuntimeObjectImp* Instance::newRuntimeObject(ExecState* exec) +{ JSLock lock(SilenceAssertionsOnly); - return new (exec) RuntimeObjectImp(exec, this); } +void Instance::willDestroyRuntimeObject() +{ + ASSERT(_rootObject); + ASSERT(_rootObject->isValid()); + ASSERT(m_runtimeObject); + _rootObject->removeRuntimeObject(m_runtimeObject); + m_runtimeObject = 0; +} + +void Instance::willInvalidateRuntimeObject() +{ + ASSERT(m_runtimeObject); + m_runtimeObject = 0; +} + RootObject* Instance::rootObject() const { return _rootObject && _rootObject->isValid() ? _rootObject.get() : 0; diff --git a/src/3rdparty/webkit/WebCore/bridge/runtime.h b/src/3rdparty/webkit/WebCore/bridge/runtime.h index e028020..6682a97 100644 --- a/src/3rdparty/webkit/WebCore/bridge/runtime.h +++ b/src/3rdparty/webkit/WebCore/bridge/runtime.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 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 @@ -86,8 +86,10 @@ public: void begin(); void end(); - virtual Class *getClass() const = 0; - virtual RuntimeObjectImp* createRuntimeObject(ExecState*); + virtual Class* getClass() const = 0; + RuntimeObjectImp* createRuntimeObject(ExecState*); + void willInvalidateRuntimeObject(); + void willDestroyRuntimeObject(); // Returns false if the value was not set successfully. virtual bool setValueOfUndefinedField(ExecState*, const Identifier&, JSValue) { return false; } @@ -117,8 +119,12 @@ public: protected: virtual void virtualBegin() { } virtual void virtualEnd() { } + virtual RuntimeObjectImp* newRuntimeObject(ExecState*); RefPtr<RootObject> _rootObject; + +private: + RuntimeObjectImp* m_runtimeObject; }; class Array : public Noncopyable { diff --git a/src/3rdparty/webkit/WebCore/bridge/runtime_object.cpp b/src/3rdparty/webkit/WebCore/bridge/runtime_object.cpp index 0282411..3fd8024 100644 --- a/src/3rdparty/webkit/WebCore/bridge/runtime_object.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/runtime_object.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 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 @@ -28,7 +28,6 @@ #include "JSDOMBinding.h" #include "runtime_method.h" -#include "runtime_root.h" #include <runtime/Error.h> #include <runtime/ObjectPrototype.h> @@ -40,38 +39,38 @@ using namespace Bindings; const ClassInfo RuntimeObjectImp::s_info = { "RuntimeObject", 0, 0, 0 }; -RuntimeObjectImp::RuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> i) +RuntimeObjectImp::RuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> instance) // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object // We need to pass in the right global object for "i". : JSObject(deprecatedGetDOMStructure<RuntimeObjectImp>(exec)) - , instance(i) + , m_instance(instance) { - instance->rootObject()->addRuntimeObject(this); } - -RuntimeObjectImp::RuntimeObjectImp(ExecState*, PassRefPtr<Structure> structure, PassRefPtr<Instance> i) + +RuntimeObjectImp::RuntimeObjectImp(ExecState*, PassRefPtr<Structure> structure, PassRefPtr<Instance> instance) : JSObject(structure) - , instance(i) + , m_instance(instance) { - instance->rootObject()->addRuntimeObject(this); } RuntimeObjectImp::~RuntimeObjectImp() { - if (instance) - instance->rootObject()->removeRuntimeObject(this); + if (m_instance) + m_instance->willDestroyRuntimeObject(); } void RuntimeObjectImp::invalidate() { - ASSERT(instance); - instance = 0; + ASSERT(m_instance); + if (m_instance) + m_instance->willInvalidateRuntimeObject(); + m_instance = 0; } JSValue RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase())); - RefPtr<Instance> instance = thisObj->instance; + RefPtr<Instance> instance = thisObj->m_instance; if (!instance) return throwInvalidAccessError(exec); @@ -89,7 +88,7 @@ JSValue RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, const Identifier JSValue RuntimeObjectImp::fieldGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase())); - RefPtr<Instance> instance = thisObj->instance; + RefPtr<Instance> instance = thisObj->m_instance; if (!instance) return throwInvalidAccessError(exec); @@ -108,7 +107,7 @@ JSValue RuntimeObjectImp::fieldGetter(ExecState* exec, const Identifier& propert JSValue RuntimeObjectImp::methodGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase())); - RefPtr<Instance> instance = thisObj->instance; + RefPtr<Instance> instance = thisObj->m_instance; if (!instance) return throwInvalidAccessError(exec); @@ -126,11 +125,13 @@ JSValue RuntimeObjectImp::methodGetter(ExecState* exec, const Identifier& proper bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) { - if (!instance) { + if (!m_instance) { throwInvalidAccessError(exec); return false; } + RefPtr<Instance> instance = m_instance; + instance->begin(); Class *aClass = instance->getClass(); @@ -169,11 +170,12 @@ bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& pro bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState *exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { - if (!instance) { + if (!m_instance) { throwInvalidAccessError(exec); return false; } + RefPtr<Instance> instance = m_instance; instance->begin(); Class *aClass = instance->getClass(); @@ -217,12 +219,12 @@ bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState *exec, const Identifie void RuntimeObjectImp::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { - if (!instance) { + if (!m_instance) { throwInvalidAccessError(exec); return; } - RefPtr<Instance> protector(instance); + RefPtr<Instance> instance = m_instance; instance->begin(); // Set the value of the property. @@ -243,10 +245,11 @@ bool RuntimeObjectImp::deleteProperty(ExecState*, const Identifier&) JSValue RuntimeObjectImp::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const { - if (!instance) + if (!m_instance) return throwInvalidAccessError(exec); - RefPtr<Instance> protector(instance); + RefPtr<Instance> instance = m_instance; + instance->begin(); JSValue result = instance->defaultValue(exec, hint); instance->end(); @@ -264,8 +267,13 @@ static JSValue JSC_HOST_CALL callRuntimeObject(ExecState* exec, JSObject* functi CallType RuntimeObjectImp::getCallData(CallData& callData) { - if (!instance || !instance->supportsInvokeDefaultMethod()) + if (!m_instance) + return CallTypeNone; + + RefPtr<Instance> instance = m_instance; + if (!instance->supportsInvokeDefaultMethod()) return CallTypeNone; + callData.native.function = callRuntimeObject; return CallTypeHost; } @@ -283,19 +291,26 @@ static JSObject* callRuntimeConstructor(ExecState* exec, JSObject* constructor, ConstructType RuntimeObjectImp::getConstructData(ConstructData& constructData) { - if (!instance || !instance->supportsConstruct()) + if (!m_instance) + return ConstructTypeNone; + + RefPtr<Instance> instance = m_instance; + if (!instance->supportsConstruct()) return ConstructTypeNone; + constructData.native.function = callRuntimeConstructor; return ConstructTypeHost; } void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - if (!instance) { + if (!m_instance) { throwInvalidAccessError(exec); return; } + RefPtr<Instance> instance = m_instance; + instance->begin(); instance->getPropertyNames(exec, propertyNames); instance->end(); diff --git a/src/3rdparty/webkit/WebCore/bridge/runtime_object.h b/src/3rdparty/webkit/WebCore/bridge/runtime_object.h index 5e8f57e..5aa02ea 100644 --- a/src/3rdparty/webkit/WebCore/bridge/runtime_object.h +++ b/src/3rdparty/webkit/WebCore/bridge/runtime_object.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 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 @@ -34,13 +34,12 @@ namespace JSC { class RuntimeObjectImp : public JSObject { public: RuntimeObjectImp(ExecState*, PassRefPtr<Bindings::Instance>); - virtual ~RuntimeObjectImp(); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool deleteProperty(ExecState* , const Identifier& propertyName); + virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; virtual CallType getCallData(CallData&); virtual ConstructType getConstructData(ConstructData&); @@ -48,8 +47,9 @@ public: virtual void getPropertyNames(ExecState*, PropertyNameArray&); virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); - virtual void invalidate(); - Bindings::Instance* getInternalInstance() const { return instance.get(); } + void invalidate(); + + Bindings::Instance* getInternalInstance() const { return m_instance.get(); } static JSObject* throwInvalidAccessError(ExecState*); @@ -75,7 +75,7 @@ private: static JSValue fieldGetter(ExecState*, const Identifier&, const PropertySlot&); static JSValue methodGetter(ExecState*, const Identifier&, const PropertySlot&); - RefPtr<Bindings::Instance> instance; + RefPtr<Bindings::Instance> m_instance; }; } // namespace diff --git a/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp index debd396..2935c31 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -1122,7 +1122,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyResize: return CSSPrimitiveValue::create(style->resize()); case CSSPropertyWebkitFontSmoothing: - return CSSPrimitiveValue::create(style->fontSmoothing()); + return CSSPrimitiveValue::create(style->fontDescription().fontSmoothing()); case CSSPropertyZIndex: if (style->hasAutoZIndex()) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); diff --git a/src/3rdparty/webkit/WebCore/css/CSSParser.cpp b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp index aa2be59..c46bf36 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSParser.cpp +++ b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp @@ -2150,7 +2150,7 @@ PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args) if (attrName[0] == '-') return 0; - if (document()->isHTMLDocument()) + if (document() && document()->isHTMLDocument()) attrName = attrName.lower(); return CSSPrimitiveValue::create(attrName, CSSPrimitiveValue::CSS_ATTR); diff --git a/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h index 70b21c4..b46322d 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h +++ b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h @@ -30,6 +30,7 @@ #include "CSSPrimitiveValue.h" #include "CSSValueKeywords.h" +#include "FontSmoothingMode.h" #include "GraphicsTypes.h" #include "Path.h" #include "RenderStyleConstants.h" @@ -1798,7 +1799,7 @@ template<> inline CSSPrimitiveValue::operator EPointerEvents() const } } -template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmoothing smoothing) +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmoothingMode smoothing) : m_type(CSS_IDENT) { switch (smoothing) { @@ -1820,7 +1821,7 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmoothing smoothing) m_value.ident = CSSValueAuto; } -template<> inline CSSPrimitiveValue::operator FontSmoothing() const +template<> inline CSSPrimitiveValue::operator FontSmoothingMode() const { switch (m_value.ident) { case CSSValueAuto: diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp index d6bcd39..dc9f2e5 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp @@ -1139,6 +1139,17 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl } #endif +#if ENABLE(MATHML) + static bool loadedMathMLUserAgentSheet; + if (e->isMathMLElement() && !loadedMathMLUserAgentSheet) { + // MathML rules. + loadedMathMLUserAgentSheet = true; + CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(mathMLSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval()); + } +#endif + #if ENABLE(WML) static bool loadedWMLUserAgentSheet; if (e->isWMLElement() && !loadedWMLUserAgentSheet) { @@ -3498,14 +3509,14 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) case CSSPropertyWebkitFontSmoothing: { FontDescription fontDescription = m_style->fontDescription(); if (isInherit) - fontDescription.setFontSmoothing(m_parentStyle->fontSmoothing()); + fontDescription.setFontSmoothing(m_parentStyle->fontDescription().fontSmoothing()); else if (isInitial) fontDescription.setFontSmoothing(AutoSmoothing); else { if (!primitiveValue) return; int id = primitiveValue->getIdent(); - FontSmoothing smoothing; + FontSmoothingMode smoothing; switch (id) { case CSSValueAuto: smoothing = AutoSmoothing; diff --git a/src/3rdparty/webkit/WebCore/css/mathml.css b/src/3rdparty/webkit/WebCore/css/mathml.css new file mode 100644 index 0000000..e725d8c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/mathml.css @@ -0,0 +1,170 @@ +@namespace "http://www.w3.org/1998/Math/MathML"; + +/* approved */ +math { + font-family: Symbol, STIXGeneral, "Times New Roman"; + display: inline-block; + padding: 0px; + margin: 0px; + text-indent: 0; + font-size: 1.1em; + vertical-align: baseline; +} +math[display="block"] { + font-family: "New Times Roman" + display: block; + text-align: center; + page-break-inside: avoid; +} + +mfrac { + vertical-align: middle; +} + +msub, msup { + display: inline-block; +} + +msub > * + * { + vertical-align: sub; + font-size: 0.75em; + line-height: 0.75em; +} + +msup > * + * { + vertical-align: super; + font-size: 0.75em; + line-height: 0.75em; +} + +msubsup > * { + margin: 0px; + padding: 0px; + vertical-align: middle; +} + +msubsup > * + * { + font-size: 0.75em; + line-height: 0.75em; +} + +munderover { + vertical-align: middle; +} + +munderover > * + *, mover > * + *, munder > * + * { + font-size: 0.75em; + line-height: 0.5625em; +} + +mrow { + line-height: 1em; + white-space: nowrap; + vertical-align: middle; +} + +mfenced > * { + vertical-align: middle; +} + +mo, mn, mi { + line-height: 0.75em; + padding: 0px; + margin: 0px; +} + +mo[mathsize="small"], mn[mathsize="small"], mi[mathsize="small"] { + font-size: 0.75em; + line-height: 0.5625em; +} + +mo[mathsize="normal"],mn[mathsize="normal"],mi[mathsize="normal"] { + font-size: 1em; + line-height: 0.75em; +} + +mo[mathsize="big"], mn[mathsize="big"], mi[mathsize="big"] { + line-height: 1.2em; + font-size: 1.5em; +} + +annotation, annotation-xml { + display:none; +} + +mphantom { + visibility: hidden; +} +merror { + outline: solid thin red; +} + +msqrt { + padding-top: 0.2em; + padding-left: 0.75em; +} + +mroot { + padding-top: 0.2em; + padding-left: 0.2em; +} + +mroot > * + * { + font-size: 0.75em; + line-height: 0.75em; + vertical-align: top; + padding-right: 0.3em; +} + +mtable { + display: inline-table; + line-height: 1.5em; + text-align: center; + vertical-align: middle; +} +mtr { + display: table-row; +} +mtd { + display: table-cell; + padding: 0 0.5ex; +} + +mtable[columnalign="left"], mtr[columnalign="left"], mtd[columnalign="left"] { + text-align: left; +} + +mtable[columnalign="right"], mtr[columnalign="right"], mtd[columnalign="right"] { + text-align: right; +} +mtable[rowalign="top"] mtd, mtable mtr[rowalign="top"] mtd, mtable mtr mtd[rowalign="top"] { + vertical-align: top; +} +mtable[rowalign="bottom"] mtd, mtable mtr[rowalign="bottom"] mtd, mtable mtr mtd[rowalign="bottom"] { + vertical-align: bottom; +} +mtable[rowalign="center"] mtd, mtable mtr[rowalign="center"] mtd, mtable mtr mtd[rowalign="center"] { + vertical-align: middle; +} +mtable[frame="solid"] { + border: solid thin; +} +mtable[frame="dashed"] { + border: dashed thin; +} +mtable[rowlines="solid"], mtable[rowlines="dashed"], mtable[columnlines="solid"], mtable[columnlines="dashed"] { + border-collapse: collapse; +} +mtable[rowlines="solid"] > mtr + mtr { + border-top: solid thin; +} +mtable[rowlines="dashed"] > mtr + mtr { + border-top: dashed thin; +} +mtable[columnlines="solid"] > mtr > mtd + mtd { + border-left: solid thin; +} +mtable[columnlines="dashed"] > mtr > mtd + mtd { + border-left: dashed thin; +} + diff --git a/src/3rdparty/webkit/WebCore/css/mediaControlsChromium.css b/src/3rdparty/webkit/WebCore/css/mediaControlsChromium.css index 0c01da2..16ff0e4 100644 --- a/src/3rdparty/webkit/WebCore/css/mediaControlsChromium.css +++ b/src/3rdparty/webkit/WebCore/css/mediaControlsChromium.css @@ -147,6 +147,7 @@ audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { height: 16px; border-color: rgba(255, 255, 255, 0.2); + border-style: solid; border-width: 1px; border-radius: 2px; background-color: rgba(255, 255, 255, 0.08); diff --git a/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h b/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h index e58d3f9..73b52d5 100644 --- a/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h +++ b/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h @@ -53,9 +53,6 @@ namespace WebCore { virtual void resume(); virtual void stop(); - protected: - virtual ~ActiveDOMObject(); - template<class T> void setPendingActivity(T* thisObject) { ASSERT(thisObject == this); @@ -70,6 +67,9 @@ namespace WebCore { thisObject->deref(); } + protected: + virtual ~ActiveDOMObject(); + private: ScriptExecutionContext* m_scriptExecutionContext; unsigned m_pendingActivityCount; diff --git a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp index 902b7ff..3c3dc37 100644 --- a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp +++ b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp @@ -187,10 +187,8 @@ void CharacterData::dispatchModifiedEvent(StringImpl* prevValue) { if (parentNode()) parentNode()->childrenChanged(); - if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) { - ExceptionCode ec; - dispatchMutationEvent(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data, ec); - } + if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) + dispatchEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data)); dispatchSubtreeModifiedEvent(); } diff --git a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp b/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp index 1ec4eb3..7274b5d 100644 --- a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp +++ b/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp @@ -41,8 +41,8 @@ namespace WebCore { -static void dispatchChildInsertionEvents(Node*, ExceptionCode&); -static void dispatchChildRemovalEvents(Node*, ExceptionCode&); +static void dispatchChildInsertionEvents(Node*); +static void dispatchChildRemovalEvents(Node*); typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue; static NodeCallbackQueue* s_postAttachCallbackQueue; @@ -144,7 +144,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce // Dispatch the mutation events. childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1); - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree. if (attached() && !child->attached() && child->parent() == this) { @@ -255,7 +255,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce allowEventDispatch(); // Dispatch the mutation events - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree if (attached() && !child->attached() && child->parent() == this) { @@ -287,7 +287,7 @@ static ExceptionCode willRemoveChild(Node *child) ExceptionCode ec = 0; // fire removed from document mutation events. - dispatchChildRemovalEvents(child, ec); + dispatchChildRemovalEvents(child); if (ec) return ec; @@ -480,7 +480,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo // Dispatch the mutation events childrenChanged(false, prev.get(), 0, 1); - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree if (attached() && !child->attached() && child->parent() == this) { @@ -864,7 +864,7 @@ Node *ContainerNode::childNode(unsigned index) const return n; } -static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec) +static void dispatchChildInsertionEvents(Node* child) { ASSERT(!eventDispatchForbidden()); @@ -878,25 +878,17 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec) document->incDOMTreeVersion(); - if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeInsertedEvent, true, c->parentNode(), String(), String(), ec); - if (ec) - return; - } + if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode())); // dispatch the DOMNodeInsertedIntoDocument event to all descendants if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) { - for (; c; c = c->traverseNextNode(child)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeInsertedIntoDocumentEvent, false, 0, String(), String(), ec); - if (ec) - return; - } + for (; c; c = c->traverseNextNode(child)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false)); } } -static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec) +static void dispatchChildRemovalEvents(Node* child) { RefPtr<Node> c = child; RefPtr<Document> document = child->document(); @@ -907,21 +899,14 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec) document->incDOMTreeVersion(); // dispatch pre-removal mutation events - if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeRemovedEvent, true, c->parentNode(), String(), String(), ec); - if (ec) - return; - } + if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode())); // dispatch the DOMNodeRemovedFromDocument event to all descendants - if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) - for (; c; c = c->traverseNextNode(child)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeRemovedFromDocumentEvent, false, 0, String(), String(), ec); - if (ec) - return; - } + if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) { + for (; c; c = c->traverseNextNode(child)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false)); + } } -} +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/Document.cpp b/src/3rdparty/webkit/WebCore/dom/Document.cpp index 1b8afe7..5422bf0 100644 --- a/src/3rdparty/webkit/WebCore/dom/Document.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Document.cpp @@ -174,6 +174,12 @@ #include "WMLNames.h" #endif +#if ENABLE(MATHML) +#include "MathMLElement.h" +#include "MathMLElementFactory.h" +#include "MathMLNames.h" +#endif + #if ENABLE(XHTMLMP) #include "HTMLNoScriptElement.h" #endif @@ -803,6 +809,10 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre else if (isWMLDocument()) e = WMLElementFactory::createWMLElement(QualifiedName(nullAtom, qName.localName(), WMLNames::wmlNamespaceURI), this, createdByParser); #endif +#if ENABLE(MATHML) + else if (qName.namespaceURI() == MathMLNames::mathmlNamespaceURI) + e = MathMLElementFactory::createMathMLElement(qName, this, createdByParser); +#endif if (!e) e = Element::create(qName, document()); @@ -1460,9 +1470,11 @@ void Document::detach() void Document::removeAllEventListeners() { + EventTarget::removeAllEventListeners(); + if (DOMWindow* domWindow = this->domWindow()) domWindow->removeAllEventListeners(); - for (Node* node = this; node; node = node->traverseNextNode()) + for (Node* node = firstChild(); node; node = node->traverseNextNode()) node->removeAllEventListeners(); } @@ -1705,8 +1717,8 @@ void Document::implicitClose() f->animation()->resumeAnimations(this); ImageLoader::dispatchPendingLoadEvents(); - dispatchLoadEvent(); - dispatchPageTransitionEvent(EventNames().pageshowEvent, false); + dispatchWindowLoadEvent(); + dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this); if (f) f->loader()->handledOnloadEvents(); #ifdef INSTRUMENT_LAYOUT_SCHEDULING @@ -2163,7 +2175,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content) FrameLoader* frameLoader = frame->loader(); if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) { frameLoader->stopAllLoaders(); - frameLoader->scheduleHTTPRedirection(0, blankURL()); + frameLoader->scheduleLocationChange(blankURL(), String()); } } } @@ -2636,7 +2648,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode) // Dispatch a change event for text fields or textareas that have been edited RenderObject* r = oldFocusedNode->renderer(); if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) { - oldFocusedNode->dispatchEvent(eventNames().changeEvent, true, false); + oldFocusedNode->dispatchEvent(Event::create(eventNames().changeEvent, true, false)); r = oldFocusedNode->renderer(); if (r && r->isTextControl()) toRenderTextControl(r)->setEdited(false); @@ -2863,26 +2875,16 @@ EventListener* Document::getWindowAttributeEventListener(const AtomicString& eve return domWindow->getAttributeEventListener(eventType); } -void Document::dispatchWindowEvent(PassRefPtr<Event> event) -{ - ASSERT(!eventDispatchForbidden()); - DOMWindow* domWindow = this->domWindow(); - if (!domWindow) - return; - ExceptionCode ec; - domWindow->dispatchEvent(event, ec); -} - -void Document::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) +void Document::dispatchWindowEvent(PassRefPtr<Event> event, PassRefPtr<EventTarget> target) { ASSERT(!eventDispatchForbidden()); DOMWindow* domWindow = this->domWindow(); if (!domWindow) return; - domWindow->dispatchEvent(eventType, canBubbleArg, cancelableArg); + domWindow->dispatchEvent(event, target); } -void Document::dispatchLoadEvent() +void Document::dispatchWindowLoadEvent() { ASSERT(!eventDispatchForbidden()); DOMWindow* domWindow = this->domWindow(); @@ -2891,15 +2893,6 @@ void Document::dispatchLoadEvent() domWindow->dispatchLoadEvent(); } -void Document::dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted) -{ - ASSERT(!eventDispatchForbidden()); - DOMWindow* domWindow = this->domWindow(); - if (!domWindow) - return; - domWindow->dispatchPageTransitionEvent(eventType, persisted); -} - PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec) { if (eventType == "Event" || eventType == "Events" || eventType == "HTMLEvents") @@ -4019,10 +4012,7 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS void Document::finishedParsing() { setParsing(false); - - ExceptionCode ec = 0; - dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false), ec); - + dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false)); if (Frame* f = frame()) f->loader()->finishedParsing(); } diff --git a/src/3rdparty/webkit/WebCore/dom/Document.h b/src/3rdparty/webkit/WebCore/dom/Document.h index bb247f3..454304b 100644 --- a/src/3rdparty/webkit/WebCore/dom/Document.h +++ b/src/3rdparty/webkit/WebCore/dom/Document.h @@ -200,6 +200,49 @@ public: // DOM methods & attributes for Document + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + + // WebKit extensions + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); + DocumentType* doctype() const { return m_docType.get(); } DOMImplementation* implementation() const; @@ -547,10 +590,8 @@ public: // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists. void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); EventListener* getWindowAttributeEventListener(const AtomicString& eventType); - void dispatchWindowEvent(PassRefPtr<Event>); - void dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg); - void dispatchLoadEvent(); - void dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted); + void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0); + void dispatchWindowLoadEvent(); PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&); @@ -812,7 +853,7 @@ public: void setDashboardRegions(const Vector<DashboardRegionValue>&); #endif - void removeAllEventListeners(); + virtual void removeAllEventListeners(); CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; } diff --git a/src/3rdparty/webkit/WebCore/dom/Element.h b/src/3rdparty/webkit/WebCore/dom/Element.h index e7a910c..4ecf932 100644 --- a/src/3rdparty/webkit/WebCore/dom/Element.h +++ b/src/3rdparty/webkit/WebCore/dom/Element.h @@ -44,6 +44,51 @@ public: static PassRefPtr<Element> create(const QualifiedName&, Document*); virtual ~Element(); + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + + // These 4 attribute event handler attributes are overrided by HTMLBodyElement + // and HTMLFrameSetElement to forward to the DOMWindow. + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load); + + // WebKit extensions + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); + const AtomicString& getIDAttribute() const; bool hasAttribute(const QualifiedName&) const; const AtomicString& getAttribute(const QualifiedName&) const; diff --git a/src/3rdparty/webkit/WebCore/dom/EventListener.h b/src/3rdparty/webkit/WebCore/dom/EventListener.h index 501c61d..6862f06 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventListener.h +++ b/src/3rdparty/webkit/WebCore/dom/EventListener.h @@ -37,13 +37,14 @@ namespace WebCore { public: enum Type { JSEventListenerType, ImageEventListenerType, - InspectorDOMAgentType, + InspectorDOMAgentType, + InspectorDOMStorageResourceType, ObjCEventListenerType, ConditionEventListenerType }; virtual ~EventListener() { } virtual bool operator==(const EventListener&) = 0; - virtual void handleEvent(Event*, bool isWindowEvent = false) = 0; + virtual void handleEvent(Event*) = 0; // Return true to indicate that the error is handled. virtual bool reportError(const String& /*message*/, const String& /*url*/, int /*lineNumber*/) { return false; } virtual bool wasCreatedFromMarkup() const { return false; } @@ -68,10 +69,6 @@ namespace WebCore { Type m_type; }; -#if USE(JSC) - inline void markIfNotNull(JSC::MarkStack& markStack, EventListener* listener) { if (listener) listener->markJSFunction(markStack); } -#endif - } #endif diff --git a/src/3rdparty/webkit/WebCore/dom/EventNames.h b/src/3rdparty/webkit/WebCore/dom/EventNames.h index 382bbf7..0eb98ec 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventNames.h +++ b/src/3rdparty/webkit/WebCore/dom/EventNames.h @@ -45,6 +45,7 @@ namespace WebCore { macro(copy) \ macro(cut) \ macro(dblclick) \ + macro(display) \ macro(downloading) \ macro(drag) \ macro(dragend) \ @@ -136,6 +137,8 @@ namespace WebCore { \ macro(webkitTransitionEnd) \ \ + macro(orientationchange) \ + \ // end of DOM_EVENT_NAMES_FOR_EACH class EventNames { diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp index 652644f..d3b3f55 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp +++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp @@ -34,11 +34,39 @@ #include "config.h" #include "EventTarget.h" +#include "Event.h" +#include "EventException.h" +#include <wtf/StdLibExtras.h> + +using namespace WTF; + namespace WebCore { #ifndef NDEBUG static int gEventDispatchForbidden = 0; -#endif + +void forbidEventDispatch() +{ + if (!isMainThread()) + return; + ++gEventDispatchForbidden; +} + +void allowEventDispatch() +{ + if (!isMainThread()) + return; + if (gEventDispatchForbidden > 0) + --gEventDispatchForbidden; +} + +bool eventDispatchForbidden() +{ + if (!isMainThread()) + return false; + return gEventDispatchForbidden > 0; +} +#endif // NDEBUG EventTarget::~EventTarget() { @@ -125,22 +153,153 @@ Notification* EventTarget::toNotification() } #endif -#ifndef NDEBUG -void forbidEventDispatch() +bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - ++gEventDispatchForbidden; + EventTargetData* d = ensureEventTargetData(); + + pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector()); + EventListenerVector& entry = result.first->second; + + RegisteredEventListener registeredListener(listener, useCapture); + if (!result.second) { // pre-existing entry + if (entry.find(registeredListener) != notFound) // duplicate listener + return false; + } + + entry.append(registeredListener); + return true; } -void allowEventDispatch() +bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - if (gEventDispatchForbidden > 0) - --gEventDispatchForbidden; + EventTargetData* d = eventTargetData(); + if (!d) + return false; + + EventListenerMap::iterator result = d->eventListenerMap.find(eventType); + if (result == d->eventListenerMap.end()) + return false; + EventListenerVector& entry = result->second; + + RegisteredEventListener registeredListener(listener, useCapture); + size_t index = entry.find(registeredListener); + if (index == notFound) + return false; + + entry.remove(index); + if (!entry.size()) + d->eventListenerMap.remove(result); + + // Notify firing events planning to invoke the listener at 'index' that + // they have one less listener to invoke. + for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) { + if (eventType == *d->firingEventEndIterators[i].eventType && index < *d->firingEventEndIterators[i].value) + --*d->firingEventEndIterators[i].value; + } + + return true; } -bool eventDispatchForbidden() +bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) { - return gEventDispatchForbidden > 0; + clearAttributeEventListener(eventType); + if (!listener) + return false; + return addEventListener(eventType, listener, false); +} + +EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType) +{ + const EventListenerVector& entry = getEventListeners(eventType); + for (size_t i = 0; i < entry.size(); ++i) { + if (entry[i].listener->isAttribute()) + return entry[i].listener.get(); + } + return 0; +} + +bool EventTarget::clearAttributeEventListener(const AtomicString& eventType) +{ + EventListener* listener = getAttributeEventListener(eventType); + if (!listener) + return false; + return removeEventListener(eventType, listener, false); +} + +bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) +{ + if (!event || event->type().isEmpty()) { + ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; + return false; + } + return dispatchEvent(event); +} + +bool EventTarget::dispatchEvent(PassRefPtr<Event> event) +{ + event->setTarget(this); + event->setCurrentTarget(this); + event->setEventPhase(Event::AT_TARGET); + return fireEventListeners(event.get()); +} + +bool EventTarget::fireEventListeners(Event* event) +{ + ASSERT(!eventDispatchForbidden()); + ASSERT(event && !event->type().isEmpty()); + + EventTargetData* d = eventTargetData(); + if (!d) + return true; + + EventListenerMap::iterator result = d->eventListenerMap.find(event->type()); + if (result == d->eventListenerMap.end()) + return false; + EventListenerVector& entry = result->second; + + RefPtr<EventTarget> protect = this; + + size_t end = entry.size(); + d->firingEventEndIterators.append(FiringEventEndIterator(&event->type(), &end)); + for (size_t i = 0; i < end; ++i) { + RegisteredEventListener& registeredListener = entry[i]; + if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture) + continue; + if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture) + continue; + // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling + // event listeners, even though that violates some versions of the DOM spec. + registeredListener.listener->handleEvent(event); + } + d->firingEventEndIterators.removeLast(); + + return !event->defaultPrevented(); +} + +const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType) +{ + DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ()); + + EventTargetData* d = eventTargetData(); + if (!d) + return emptyVector; + EventListenerMap::iterator it = d->eventListenerMap.find(eventType); + if (it == d->eventListenerMap.end()) + return emptyVector; + return it->second; +} + +void EventTarget::removeAllEventListeners() +{ + EventTargetData* d = eventTargetData(); + if (!d) + return; + d->eventListenerMap.clear(); + + // Notify firing events planning to invoke the listener at 'index' that + // they have one less listener to invoke. + for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) + *d->firingEventEndIterators[i].value = 0; } -#endif // NDEBUG -} // end namespace +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.h b/src/3rdparty/webkit/WebCore/dom/EventTarget.h index 6bcc3fb..4499328 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventTarget.h +++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.h @@ -32,6 +32,9 @@ #ifndef EventTarget_h #define EventTarget_h +#include "AtomicStringHash.h" +#include "EventNames.h" +#include "RegisteredEventListener.h" #include <wtf/Forward.h> namespace WebCore { @@ -58,8 +61,31 @@ namespace WebCore { typedef int ExceptionCode; + struct FiringEventEndIterator { + FiringEventEndIterator(const AtomicString* eventType, size_t* value) + : eventType(eventType) + , value(value) + { + } + + const AtomicString* eventType; + size_t* value; + }; + typedef Vector<FiringEventEndIterator, 1> FiringEventEndIteratorVector; + + typedef Vector<RegisteredEventListener, 1> EventListenerVector; + typedef HashMap<AtomicString, EventListenerVector> EventListenerMap; + + struct EventTargetData { + EventListenerMap eventListenerMap; + FiringEventEndIteratorVector firingEventEndIterators; + }; + class EventTarget { public: + void ref() { refEventTarget(); } + void deref() { derefEventTarget(); } + virtual EventSource* toEventSource(); virtual MessagePort* toMessagePort(); virtual Node* toNode(); @@ -90,36 +116,119 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const = 0; - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) = 0; - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) = 0; - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&) = 0; + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual void removeAllEventListeners(); + virtual bool dispatchEvent(PassRefPtr<Event>); + bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API - void ref() { refEventTarget(); } - void deref() { derefEventTarget(); } + // Used for legacy "onEvent" attribute APIs. + bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); + bool clearAttributeEventListener(const AtomicString& eventType); + EventListener* getAttributeEventListener(const AtomicString& eventType); + + bool hasEventListeners(); + bool hasEventListeners(const AtomicString& eventType); + const EventListenerVector& getEventListeners(const AtomicString& eventType); - // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event - // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. - virtual void* preDispatchEventHandler(Event*) { return 0; } - virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } + bool fireEventListeners(Event*); + bool isFiringEventListeners(); + +#if USE(JSC) + void markEventListeners(JSC::MarkStack&); + void invalidateEventListeners(); +#endif protected: virtual ~EventTarget(); + + virtual EventTargetData* eventTargetData() = 0; + virtual EventTargetData* ensureEventTargetData() = 0; private: virtual void refEventTarget() = 0; virtual void derefEventTarget() = 0; }; - void forbidEventDispatch(); - void allowEventDispatch(); + #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ + EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ + virtual EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ + virtual void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ + EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ + EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ + + #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ + EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ #ifndef NDEBUG + void forbidEventDispatch(); + void allowEventDispatch(); bool eventDispatchForbidden(); #else inline void forbidEventDispatch() { } inline void allowEventDispatch() { } #endif -} +#if USE(JSC) + inline void EventTarget::markEventListeners(JSC::MarkStack& markStack) + { + EventTargetData* d = eventTargetData(); + if (!d) + return; + + EventListenerMap::iterator end = d->eventListenerMap.end(); + for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) { + EventListenerVector& entry = it->second; + for (size_t i = 0; i < entry.size(); ++i) + entry[i].listener->markJSFunction(markStack); + } + } + + inline void EventTarget::invalidateEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return; + + d->eventListenerMap.clear(); + } + + inline bool EventTarget::isFiringEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return d->firingEventEndIterators.size() != 0; + } + + inline bool EventTarget::hasEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return !d->eventListenerMap.isEmpty(); + } + + inline bool EventTarget::hasEventListeners(const AtomicString& eventType) + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return d->eventListenerMap.contains(eventType); + } #endif + +} // namespace WebCore + +#endif // EventTarget_h diff --git a/src/3rdparty/webkit/WebCore/dom/InputElement.cpp b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp index 97793e2..96e31f4 100644 --- a/src/3rdparty/webkit/WebCore/dom/InputElement.cpp +++ b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp @@ -34,7 +34,6 @@ #include "RenderTextControlSingleLine.h" #include "SelectionController.h" #include "TextIterator.h" -#include "TextBreakIterator.h" #if ENABLE(WML) #include "WMLInputElement.h" @@ -154,28 +153,10 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in element->setFormControlValueMatchesRenderer(true); - // Fire the "input" DOM event - element->dispatchEvent(eventNames().inputEvent, true, false); + element->dispatchEvent(Event::create(eventNames().inputEvent, true, false)); notifyFormStateChanged(element); } -static int numCharactersInGraphemeClusters(StringImpl* s, int numGraphemeClusters) -{ - if (!s) - return 0; - - TextBreakIterator* it = characterBreakIterator(s->characters(), s->length()); - if (!it) - return 0; - - for (int i = 0; i < numGraphemeClusters; ++i) { - if (textBreakNext(it) == TextBreakDone) - return s->length(); - } - - return textBreakCurrent(it); -} - String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue) { return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength); @@ -191,36 +172,15 @@ String InputElement::sanitizeUserInputValue(const InputElement* inputElement, co string.replace('\r', ' '); string.replace('\n', ' '); - StringImpl* s = string.impl(); - int newLength = numCharactersInGraphemeClusters(s, maxLength); - for (int i = 0; i < newLength; ++i) { - const UChar& current = (*s)[i]; + unsigned newLength = string.numCharactersInGraphemeClusters(maxLength); + for (unsigned i = 0; i < newLength; ++i) { + const UChar current = string[i]; if (current < ' ' && current != '\t') { newLength = i; break; } } - - if (newLength < static_cast<int>(string.length())) - return string.left(newLength); - - return string; -} - -static int numGraphemeClusters(StringImpl* s) -{ - if (!s) - return 0; - - TextBreakIterator* it = characterBreakIterator(s->characters(), s->length()); - if (!it) - return 0; - - int num = 0; - while (textBreakNext(it) != TextBreakDone) - ++num; - - return num; + return string.left(newLength); } void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Element* element, Event* event) @@ -231,15 +191,16 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputEl // We use RenderTextControlSingleLine::text() instead of InputElement::value() // because they can be mismatched by sanitizeValue() in // RenderTextControlSingleLine::subtreeHasChanged() in some cases. - int oldLength = numGraphemeClusters(toRenderTextControlSingleLine(element->renderer())->text().impl()); + unsigned oldLength = toRenderTextControlSingleLine(element->renderer())->text().numGraphemeClusters(); // selection() may be a pre-edit text. - int selectionLength = numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()).impl()); + unsigned selectionLength = plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()).numGraphemeClusters(); ASSERT(oldLength >= selectionLength); // Selected characters will be removed by the next text event. - int baseLength = oldLength - selectionLength; - int appendableLength = data.maxLength() - baseLength; + unsigned baseLength = oldLength - selectionLength; + unsigned maxLength = static_cast<unsigned>(data.maxLength()); // maxLength() can never be negative. + unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; // Truncate the inserted text to avoid violating the maxLength and other constraints. BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event); diff --git a/src/3rdparty/webkit/WebCore/dom/MessageEvent.h b/src/3rdparty/webkit/WebCore/dom/MessageEvent.h index 7d94689..555ed47 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessageEvent.h +++ b/src/3rdparty/webkit/WebCore/dom/MessageEvent.h @@ -42,7 +42,7 @@ namespace WebCore { { return adoptRef(new MessageEvent); } - static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports) + static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& data = "", const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0) { return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports)); } diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp index bfd7932..50a0106 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp @@ -169,13 +169,7 @@ void MessagePort::dispatchMessages() OwnPtr<MessagePortChannel::EventData> eventData; while (m_entangledChannel && m_entangledChannel->tryGetMessageFromRemote(eventData)) { OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, eventData->channels()); - RefPtr<Event> evt = MessageEvent::create(eventData->message(), "", "", 0, ports.release()); - - if (m_onMessageListener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onMessageListener->handleEvent(evt.get(), false); - } + RefPtr<Event> evt = MessageEvent::create(ports.release(), eventData->message()); ExceptionCode ec = 0; dispatchEvent(evt.release(), ec); @@ -183,63 +177,6 @@ void MessagePort::dispatchMessages() } } -void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void MessagePort::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - -void MessagePort::setOnmessage(PassRefPtr<EventListener> eventListener) -{ - m_onMessageListener = eventListener; - start(); -} - bool MessagePort::hasPendingActivity() { // The spec says that entangled message ports should always be treated as if they have a strong reference. @@ -294,4 +231,14 @@ PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionContext& return portArray; } +EventTargetData* MessagePort::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* MessagePort::ensureEventTargetData() +{ + return &m_eventTargetData; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.h b/src/3rdparty/webkit/WebCore/dom/MessagePort.h index d042bc1..e649d5d 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.h +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.h @@ -29,9 +29,9 @@ #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "MessagePortChannel.h" - #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -87,21 +87,17 @@ namespace WebCore { void dispatchMessages(); - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } - using RefCounted<MessagePort>::ref; using RefCounted<MessagePort>::deref; bool hasPendingActivity(); - void setOnmessage(PassRefPtr<EventListener>); - EventListener* onmessage() const { return m_onMessageListener.get(); } + void setOnmessage(PassRefPtr<EventListener> listener) + { + setAttributeEventListener(eventNames().messageEvent, listener); + start(); + } + EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); } // Returns null if there is no entangled port, or if the entangled port is run by a different thread. // Returns null otherwise. @@ -114,16 +110,15 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); OwnPtr<MessagePortChannel> m_entangledChannel; bool m_started; ScriptExecutionContext* m_scriptExecutionContext; - - RefPtr<EventListener> m_onMessageListener; - - EventListenersMap m_eventListeners; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl index 11ab757..a9149ec 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl @@ -28,6 +28,7 @@ module events { interface [ CustomMarkFunction, + EventTarget, GenerateConstructor, NoStaticTables ] MessagePort { diff --git a/src/3rdparty/webkit/WebCore/dom/MutationEvent.h b/src/3rdparty/webkit/WebCore/dom/MutationEvent.h index c5f2d1d..29b978c 100644 --- a/src/3rdparty/webkit/WebCore/dom/MutationEvent.h +++ b/src/3rdparty/webkit/WebCore/dom/MutationEvent.h @@ -41,10 +41,11 @@ namespace WebCore { { return adoptRef(new MutationEvent); } - static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode, - const String& prevValue, const String& newValue, const String& attrName, unsigned short attrChange) + + static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0, + const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0) { - return adoptRef(new MutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange)); + return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange)); } void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode, diff --git a/src/3rdparty/webkit/WebCore/dom/Node.cpp b/src/3rdparty/webkit/WebCore/dom/Node.cpp index a26dd04..2240dd8 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Node.cpp @@ -2342,16 +2342,6 @@ ScriptExecutionContext* Node::scriptExecutionContext() const return document(); } -const RegisteredEventListenerVector& Node::eventListeners() const -{ - if (hasRareData()) { - if (RegisteredEventListenerVector* listeners = rareData()->listeners()) - return *listeners; - } - static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector; - return *emptyListenersVector; -} - void Node::insertedIntoDocument() { setInDocument(true); @@ -2399,69 +2389,45 @@ static inline void updateSVGElementInstancesAfterEventListenerChange(Node* refer #endif } -void Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) +bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { + if (!EventTarget::addEventListener(eventType, listener, useCapture)) + return false; + if (Document* document = this->document()) document->addListenerTypeIfNeeded(eventType); - - RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners(); - - // Remove existing identical listener set with identical arguments. - // The DOM2 spec says that "duplicate instances are discarded" in this case. - removeEventListener(eventType, listener.get(), useCapture); - - listeners.append(RegisteredEventListener::create(eventType, listener, useCapture)); updateSVGElementInstancesAfterEventListenerChange(this); + return true; } -void Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) +bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - if (!hasRareData()) - return; - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; - - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listeners->at(i); - if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) { - r.setRemoved(true); - listeners->remove(i); + if (!EventTarget::removeEventListener(eventType, listener, useCapture)) + return false; - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } - } + updateSVGElementInstancesAfterEventListenerChange(this); + return true; } -void Node::removeAllEventListenersSlowCase() +EventTargetData* Node::eventTargetData() { - ASSERT(hasRareData()); - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; + return hasRareData() ? rareData()->eventTargetData() : 0; +} - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) - listeners->at(i)->setRemoved(true); - listeners->clear(); +EventTargetData* Node::ensureEventTargetData() +{ + return ensureRareData()->ensureEventTargetData(); } -void Node::handleLocalEvents(Event* event, bool useCapture) +void Node::handleLocalEvents(Event* event) { + if (!hasRareData() || !rareData()->eventTargetData()) + return; + if (disabled() && event->isMouseEvent()) return; - RegisteredEventListenerVector listenersCopy = eventListeners(); - size_t size = listenersCopy.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listenersCopy[i]; - if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed()) - r.listener()->handleEvent(event, false); - } + fireEventListeners(event); } #if ENABLE(SVG) @@ -2502,19 +2468,15 @@ static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNo return referenceNode; } -bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) +bool Node::dispatchEvent(PassRefPtr<Event> prpEvent) { - RefPtr<Event> evt(e); - ASSERT(!eventDispatchForbidden()); - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return false; - } + RefPtr<EventTarget> protect = this; + RefPtr<Event> event = prpEvent; - evt->setTarget(eventTargetRespectingSVGTargetRules(this)); + event->setTarget(eventTargetRespectingSVGTargetRules(this)); RefPtr<FrameView> view = document()->view(); - return dispatchGenericEvent(evt.release()); + return dispatchGenericEvent(event.release()); } bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) @@ -2567,27 +2529,22 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) if (targetForWindowEvents) { event->setCurrentTarget(targetForWindowEvents); - targetForWindowEvents->handleEvent(event.get(), true); + targetForWindowEvents->fireEventListeners(event.get()); if (event->propagationStopped()) goto doneDispatching; } for (size_t i = ancestors.size(); i; --i) { ContainerNode* ancestor = ancestors[i - 1].get(); event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); - ancestor->handleLocalEvents(event.get(), true); + ancestor->handleLocalEvents(event.get()); if (event->propagationStopped()) goto doneDispatching; } event->setEventPhase(Event::AT_TARGET); - // We do want capturing event listeners to be invoked here, even though - // that violates some versions of the DOM specification; Mozilla does it. event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this)); - handleLocalEvents(event.get(), true); - if (event->propagationStopped()) - goto doneDispatching; - handleLocalEvents(event.get(), false); + handleLocalEvents(event.get()); if (event->propagationStopped()) goto doneDispatching; @@ -2599,13 +2556,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) for (size_t i = 0; i < size; ++i) { ContainerNode* ancestor = ancestors[i].get(); event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); - ancestor->handleLocalEvents(event.get(), false); + ancestor->handleLocalEvents(event.get()); if (event->propagationStopped() || event->cancelBubble()) goto doneDispatching; } if (targetForWindowEvents) { event->setCurrentTarget(targetForWindowEvents); - targetForWindowEvents->handleEvent(event.get(), false); + targetForWindowEvents->fireEventListeners(event.get()); if (event->propagationStopped() || event->cancelBubble()) goto doneDispatching; } @@ -2663,8 +2620,7 @@ void Node::dispatchSubtreeModifiedEvent() if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER)) return; - ExceptionCode ec = 0; - dispatchMutationEvent(eventNames().DOMSubtreeModifiedEvent, true, 0, String(), String(), ec); + dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true)); } void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent) @@ -2674,18 +2630,15 @@ void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr bool cancelable = eventType == eventNames().DOMActivateEvent; - ExceptionCode ec = 0; - RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail); - evt->setUnderlyingEvent(underlyingEvent); - dispatchEvent(evt.release(), ec); + RefPtr<UIEvent> event = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail); + event->setUnderlyingEvent(underlyingEvent); + dispatchEvent(event.release()); } bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key) { - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView()); - bool r = dispatchEvent(keyboardEvent, ec); + bool r = dispatchEvent(keyboardEvent); // we want to return false if default is prevented (already taken care of) // or if the element is default-handled by the DOM. Otherwise we let it just @@ -2779,8 +2732,6 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det bool cancelable = eventType != eventNames().mousemoveEvent; - ExceptionCode ec = 0; - bool swallowEvent = false; // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored. @@ -2805,7 +2756,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det mouseEvent->setUnderlyingEvent(underlyingEvent.get()); mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY)); - dispatchEvent(mouseEvent, ec); + dispatchEvent(mouseEvent); bool defaultHandled = mouseEvent->defaultHandled(); bool defaultPrevented = mouseEvent->defaultPrevented(); if (defaultHandled || defaultPrevented) @@ -2823,7 +2774,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det doubleClickEvent->setUnderlyingEvent(underlyingEvent.get()); if (defaultHandled) doubleClickEvent->setDefaultHandled(); - dispatchEvent(doubleClickEvent, ec); + dispatchEvent(doubleClickEvent); if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented()) swallowEvent = true; } @@ -2860,98 +2811,18 @@ void Node::dispatchWheelEvent(PlatformWheelEvent& e) we->setAbsoluteLocation(IntPoint(pos.x(), pos.y())); - ExceptionCode ec = 0; - if (!dispatchEvent(we.release(), ec)) + if (!dispatchEvent(we.release())) e.accept(); } -void Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec); -} - -void Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec); -} - -void Node::dispatchMutationEvent(const AtomicString& eventType, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode& ec) -{ - ASSERT(!eventDispatchForbidden()); - - dispatchEvent(MutationEvent::create(eventType, canBubble, false, relatedNode, prevValue, newValue, String(), 0), ec); -} - void Node::dispatchFocusEvent() { - dispatchEvent(eventNames().focusEvent, false, false); + dispatchEvent(Event::create(eventNames().focusEvent, false, false)); } void Node::dispatchBlurEvent() { - dispatchEvent(eventNames().blurEvent, false, false); -} - -bool Node::dispatchEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec); -} - -void Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec); -} - -void Node::clearAttributeEventListener(const AtomicString& eventType) -{ - if (!hasRareData()) - return; - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; - - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listeners->at(i); - if (r.eventType() != eventType || !r.listener()->isAttribute()) - continue; - - r.setRemoved(true); - listeners->remove(i); - - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } -} - -void Node::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) -{ - clearAttributeEventListener(eventType); - if (listener) - addEventListener(eventType, listener, false); -} - -EventListener* Node::getAttributeEventListener(const AtomicString& eventType) const -{ - const RegisteredEventListenerVector& listeners = eventListeners(); - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listeners[i]; - if (r.eventType() == eventType && r.listener()->isAttribute()) - return r.listener(); - } - return 0; + dispatchEvent(Event::create(eventNames().blurEvent, false, false)); } bool Node::disabled() const @@ -2984,396 +2855,6 @@ void Node::defaultEventHandler(Event* event) } } -EventListener* Node::onabort() const -{ - return getAttributeEventListener(eventNames().abortEvent); -} - -void Node::setOnabort(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().abortEvent, eventListener); -} - -EventListener* Node::onblur() const -{ - return getAttributeEventListener(eventNames().blurEvent); -} - -void Node::setOnblur(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* Node::onchange() const -{ - return getAttributeEventListener(eventNames().changeEvent); -} - -void Node::setOnchange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().changeEvent, eventListener); -} - -EventListener* Node::onclick() const -{ - return getAttributeEventListener(eventNames().clickEvent); -} - -void Node::setOnclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().clickEvent, eventListener); -} - -EventListener* Node::oncontextmenu() const -{ - return getAttributeEventListener(eventNames().contextmenuEvent); -} - -void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().contextmenuEvent, eventListener); -} - -EventListener* Node::ondblclick() const -{ - return getAttributeEventListener(eventNames().dblclickEvent); -} - -void Node::setOndblclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dblclickEvent, eventListener); -} - -EventListener* Node::onerror() const -{ - return getAttributeEventListener(eventNames().errorEvent); -} - -void Node::setOnerror(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* Node::onfocus() const -{ - return getAttributeEventListener(eventNames().focusEvent); -} - -void Node::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* Node::oninput() const -{ - return getAttributeEventListener(eventNames().inputEvent); -} - -void Node::setOninput(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().inputEvent, eventListener); -} - -EventListener* Node::oninvalid() const -{ - return getAttributeEventListener(eventNames().invalidEvent); -} - -void Node::setOninvalid(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().invalidEvent, eventListener); -} - -EventListener* Node::onkeydown() const -{ - return getAttributeEventListener(eventNames().keydownEvent); -} - -void Node::setOnkeydown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keydownEvent, eventListener); -} - -EventListener* Node::onkeypress() const -{ - return getAttributeEventListener(eventNames().keypressEvent); -} - -void Node::setOnkeypress(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keypressEvent, eventListener); -} - -EventListener* Node::onkeyup() const -{ - return getAttributeEventListener(eventNames().keyupEvent); -} - -void Node::setOnkeyup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keyupEvent, eventListener); -} - -EventListener* Node::onload() const -{ - return getAttributeEventListener(eventNames().loadEvent); -} - -void Node::setOnload(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* Node::onmousedown() const -{ - return getAttributeEventListener(eventNames().mousedownEvent); -} - -void Node::setOnmousedown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousedownEvent, eventListener); -} - -EventListener* Node::onmousemove() const -{ - return getAttributeEventListener(eventNames().mousemoveEvent); -} - -void Node::setOnmousemove(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousemoveEvent, eventListener); -} - -EventListener* Node::onmouseout() const -{ - return getAttributeEventListener(eventNames().mouseoutEvent); -} - -void Node::setOnmouseout(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoutEvent, eventListener); -} - -EventListener* Node::onmouseover() const -{ - return getAttributeEventListener(eventNames().mouseoverEvent); -} - -void Node::setOnmouseover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoverEvent, eventListener); -} - -EventListener* Node::onmouseup() const -{ - return getAttributeEventListener(eventNames().mouseupEvent); -} - -void Node::setOnmouseup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseupEvent, eventListener); -} - -EventListener* Node::onmousewheel() const -{ - return getAttributeEventListener(eventNames().mousewheelEvent); -} - -void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousewheelEvent, eventListener); -} - -EventListener* Node::ondragenter() const -{ - return getAttributeEventListener(eventNames().dragenterEvent); -} - -void Node::setOndragenter(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragenterEvent, eventListener); -} - -EventListener* Node::ondragover() const -{ - return getAttributeEventListener(eventNames().dragoverEvent); -} - -void Node::setOndragover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragoverEvent, eventListener); -} - -EventListener* Node::ondragleave() const -{ - return getAttributeEventListener(eventNames().dragleaveEvent); -} - -void Node::setOndragleave(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragleaveEvent, eventListener); -} - -EventListener* Node::ondrop() const -{ - return getAttributeEventListener(eventNames().dropEvent); -} - -void Node::setOndrop(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dropEvent, eventListener); -} - -EventListener* Node::ondragstart() const -{ - return getAttributeEventListener(eventNames().dragstartEvent); -} - -void Node::setOndragstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragstartEvent, eventListener); -} - -EventListener* Node::ondrag() const -{ - return getAttributeEventListener(eventNames().dragEvent); -} - -void Node::setOndrag(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragEvent, eventListener); -} - -EventListener* Node::ondragend() const -{ - return getAttributeEventListener(eventNames().dragendEvent); -} - -void Node::setOndragend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragendEvent, eventListener); -} - -EventListener* Node::onscroll() const -{ - return getAttributeEventListener(eventNames().scrollEvent); -} - -void Node::setOnscroll(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().scrollEvent, eventListener); -} - -EventListener* Node::onselect() const -{ - return getAttributeEventListener(eventNames().selectEvent); -} - -void Node::setOnselect(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().selectEvent, eventListener); -} - -EventListener* Node::onsubmit() const -{ - return getAttributeEventListener(eventNames().submitEvent); -} - -void Node::setOnsubmit(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().submitEvent, eventListener); -} - -EventListener* Node::onbeforecut() const -{ - return getAttributeEventListener(eventNames().beforecutEvent); -} - -void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforecutEvent, eventListener); -} - -EventListener* Node::oncut() const -{ - return getAttributeEventListener(eventNames().cutEvent); -} - -void Node::setOncut(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().cutEvent, eventListener); -} - -EventListener* Node::onbeforecopy() const -{ - return getAttributeEventListener(eventNames().beforecopyEvent); -} - -void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforecopyEvent, eventListener); -} - -EventListener* Node::oncopy() const -{ - return getAttributeEventListener(eventNames().copyEvent); -} - -void Node::setOncopy(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().copyEvent, eventListener); -} - -EventListener* Node::onbeforepaste() const -{ - return getAttributeEventListener(eventNames().beforepasteEvent); -} - -void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforepasteEvent, eventListener); -} - -EventListener* Node::onpaste() const -{ - return getAttributeEventListener(eventNames().pasteEvent); -} - -void Node::setOnpaste(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().pasteEvent, eventListener); -} - -EventListener* Node::onreset() const -{ - return getAttributeEventListener(eventNames().resetEvent); -} - -void Node::setOnreset(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().resetEvent, eventListener); -} - -EventListener* Node::onsearch() const -{ - return getAttributeEventListener(eventNames().searchEvent); -} - -void Node::setOnsearch(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().searchEvent, eventListener); -} - -EventListener* Node::onselectstart() const -{ - return getAttributeEventListener(eventNames().selectstartEvent); -} - -void Node::setOnselectstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().selectstartEvent, eventListener); -} - } // namespace WebCore #ifndef NDEBUG diff --git a/src/3rdparty/webkit/WebCore/dom/Node.h b/src/3rdparty/webkit/WebCore/dom/Node.h index af1e73b..f3bebc6 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.h +++ b/src/3rdparty/webkit/WebCore/dom/Node.h @@ -183,6 +183,13 @@ public: static bool isWMLElement() { return false; } #endif +#if ENABLE(MATHML) + virtual bool isMathMLElement() const { return false; } +#else + static bool isMathMLElement() { return false; } +#endif + + virtual bool isMediaControlElement() const { return false; } virtual bool isStyledElement() const { return false; } virtual bool isFrameOwnerElement() const { return false; } @@ -505,19 +512,19 @@ public: virtual ScriptExecutionContext* scriptExecutionContext() const; - // Used for standard DOM addEventListener / removeEventListener APIs. - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - // Used for legacy "onEvent" property APIs. - void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); - void clearAttributeEventListener(const AtomicString& eventType); - EventListener* getAttributeEventListener(const AtomicString& eventType) const; + // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event + // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. + virtual void* preDispatchEventHandler(Event*) { return 0; } + virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - bool dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable); + using EventTarget::dispatchEvent; + virtual bool dispatchEvent(PassRefPtr<Event>); - void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); } + bool dispatchGenericEvent(PassRefPtr<Event>); + virtual void handleLocalEvents(Event*); void dispatchSubtreeModifiedEvent(); void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent); @@ -531,14 +538,6 @@ public: bool isSimulated, Node* relatedTarget, PassRefPtr<Event> underlyingEvent); void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent); void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true); - void dispatchProgressEvent(const AtomicString& eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg); - void dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime); - void dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime); - void dispatchMutationEvent(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode&); - - bool dispatchGenericEvent(PassRefPtr<Event>); - - virtual void handleLocalEvents(Event*, bool useCapture); virtual void dispatchFocusEvent(); virtual void dispatchBlurEvent(); @@ -554,95 +553,12 @@ public: */ virtual bool disabled() const; - const RegisteredEventListenerVector& eventListeners() const; - - // These 4 attribute event handler attributes are overrided by HTMLBodyElement - // and HTMLFrameSetElement to forward to the DOMWindow. - virtual EventListener* onblur() const; - virtual void setOnblur(PassRefPtr<EventListener>); - virtual EventListener* onerror() const; - virtual void setOnerror(PassRefPtr<EventListener>); - virtual EventListener* onfocus() const; - virtual void setOnfocus(PassRefPtr<EventListener>); - virtual EventListener* onload() const; - virtual void setOnload(PassRefPtr<EventListener>); - - EventListener* onabort() const; - void setOnabort(PassRefPtr<EventListener>); - EventListener* onchange() const; - void setOnchange(PassRefPtr<EventListener>); - EventListener* onclick() const; - void setOnclick(PassRefPtr<EventListener>); - EventListener* oncontextmenu() const; - void setOncontextmenu(PassRefPtr<EventListener>); - EventListener* ondblclick() const; - void setOndblclick(PassRefPtr<EventListener>); - EventListener* ondragenter() const; - void setOndragenter(PassRefPtr<EventListener>); - EventListener* ondragover() const; - void setOndragover(PassRefPtr<EventListener>); - EventListener* ondragleave() const; - void setOndragleave(PassRefPtr<EventListener>); - EventListener* ondrop() const; - void setOndrop(PassRefPtr<EventListener>); - EventListener* ondragstart() const; - void setOndragstart(PassRefPtr<EventListener>); - EventListener* ondrag() const; - void setOndrag(PassRefPtr<EventListener>); - EventListener* ondragend() const; - void setOndragend(PassRefPtr<EventListener>); - EventListener* oninput() const; - void setOninput(PassRefPtr<EventListener>); - EventListener* oninvalid() const; - void setOninvalid(PassRefPtr<EventListener>); - EventListener* onkeydown() const; - void setOnkeydown(PassRefPtr<EventListener>); - EventListener* onkeypress() const; - void setOnkeypress(PassRefPtr<EventListener>); - EventListener* onkeyup() const; - void setOnkeyup(PassRefPtr<EventListener>); - EventListener* onmousedown() const; - void setOnmousedown(PassRefPtr<EventListener>); - EventListener* onmousemove() const; - void setOnmousemove(PassRefPtr<EventListener>); - EventListener* onmouseout() const; - void setOnmouseout(PassRefPtr<EventListener>); - EventListener* onmouseover() const; - void setOnmouseover(PassRefPtr<EventListener>); - EventListener* onmouseup() const; - void setOnmouseup(PassRefPtr<EventListener>); - EventListener* onmousewheel() const; - void setOnmousewheel(PassRefPtr<EventListener>); - EventListener* onscroll() const; - void setOnscroll(PassRefPtr<EventListener>); - EventListener* onselect() const; - void setOnselect(PassRefPtr<EventListener>); - EventListener* onsubmit() const; - void setOnsubmit(PassRefPtr<EventListener>); - - // WebKit extensions - EventListener* onbeforecut() const; - void setOnbeforecut(PassRefPtr<EventListener>); - EventListener* oncut() const; - void setOncut(PassRefPtr<EventListener>); - EventListener* onbeforecopy() const; - void setOnbeforecopy(PassRefPtr<EventListener>); - EventListener* oncopy() const; - void setOncopy(PassRefPtr<EventListener>); - EventListener* onbeforepaste() const; - void setOnbeforepaste(PassRefPtr<EventListener>); - EventListener* onpaste() const; - void setOnpaste(PassRefPtr<EventListener>); - EventListener* onreset() const; - void setOnreset(PassRefPtr<EventListener>); - EventListener* onsearch() const; - void setOnsearch(PassRefPtr<EventListener>); - EventListener* onselectstart() const; - void setOnselectstart(PassRefPtr<EventListener>); - using TreeShared<Node>::ref; using TreeShared<Node>::deref; + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); + protected: // CreateElementZeroRefCount is deprecated and can be removed once we convert all element // classes to start with a reference count of 1. diff --git a/src/3rdparty/webkit/WebCore/dom/Node.idl b/src/3rdparty/webkit/WebCore/dom/Node.idl index 1e31aea..45ea132 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.idl +++ b/src/3rdparty/webkit/WebCore/dom/Node.idl @@ -24,6 +24,7 @@ module core { CustomMarkFunction, CustomPushEventHandlerScope, CustomToJS, + EventTarget, GenerateConstructor, GenerateNativeConverter, InlineGetOwnPropertySlot, diff --git a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h index 7740344..8b9e1bf 100644 --- a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h +++ b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h @@ -93,12 +93,12 @@ public: void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; } bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; } - RegisteredEventListenerVector* listeners() { return m_eventListeners.get(); } - RegisteredEventListenerVector& ensureListeners() + EventTargetData* eventTargetData() { return m_eventTargetData.get(); } + EventTargetData* ensureEventTargetData() { - if (!m_eventListeners) - m_eventListeners.set(new RegisteredEventListenerVector); - return *m_eventListeners; + if (!m_eventTargetData) + m_eventTargetData.set(new EventTargetData); + return m_eventTargetData.get(); } bool isFocused() const { return m_isFocused; } @@ -111,7 +111,7 @@ protected: private: OwnPtr<NodeListsNodeData> m_nodeLists; - OwnPtr<RegisteredEventListenerVector > m_eventListeners; + OwnPtr<EventTargetData> m_eventTargetData; short m_tabIndex; bool m_tabIndexWasSetExplicitly : 1; bool m_isFocused : 1; diff --git a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp index f257e56..e8bc594 100644 --- a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp +++ b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp @@ -27,12 +27,4 @@ namespace WebCore { -RegisteredEventListener::RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) - : m_eventType(eventType) - , m_listener(listener) - , m_useCapture(useCapture) - , m_removed(false) -{ -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h index 034f6c3..88d2279 100644 --- a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h +++ b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h @@ -29,47 +29,21 @@ namespace WebCore { - class RegisteredEventListener : public RefCounted<RegisteredEventListener> { - public: - static PassRefPtr<RegisteredEventListener> create(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) + struct RegisteredEventListener { + RegisteredEventListener(PassRefPtr<EventListener> listener, bool useCapture) + : listener(listener) + , useCapture(useCapture) { - return adoptRef(new RegisteredEventListener(eventType, listener, useCapture)); } - const AtomicString& eventType() const { return m_eventType; } - EventListener* listener() const { return m_listener.get(); } - bool useCapture() const { return m_useCapture; } - - bool removed() const { return m_removed; } - void setRemoved(bool removed) { m_removed = removed; } - - private: - RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - - AtomicString m_eventType; - RefPtr<EventListener> m_listener; - bool m_useCapture; - bool m_removed; + RefPtr<EventListener> listener; + bool useCapture; }; - - typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector; - -#if USE(JSC) - inline void markEventListeners(JSC::MarkStack& markStack, const RegisteredEventListenerVector& listeners) - { - for (size_t i = 0; i < listeners.size(); ++i) - listeners[i]->listener()->markJSFunction(markStack); - } - - inline void invalidateEventListeners(const RegisteredEventListenerVector& listeners) + + inline bool operator==(const RegisteredEventListener& a, const RegisteredEventListener& b) { - // For efficiency's sake, we just set the "removed" bit, instead of - // actually removing the event listener. The node that owns these - // listeners is about to be deleted, anyway. - for (size_t i = 0; i < listeners.size(); ++i) - listeners[i]->setRemoved(true); + return *a.listener == *b.listener && a.useCapture == b.useCapture; } -#endif } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/generated/HTMLNames.cpp b/src/3rdparty/webkit/WebCore/generated/HTMLNames.cpp index d259fc2..4e51f54 100644 --- a/src/3rdparty/webkit/WebCore/generated/HTMLNames.cpp +++ b/src/3rdparty/webkit/WebCore/generated/HTMLNames.cpp @@ -451,6 +451,7 @@ DEFINE_GLOBAL(QualifiedName, onmouseupAttr, nullAtom, "onmouseup", xhtmlNamespac DEFINE_GLOBAL(QualifiedName, onmousewheelAttr, nullAtom, "onmousewheel", xhtmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, onofflineAttr, nullAtom, "onoffline", xhtmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, ononlineAttr, nullAtom, "ononline", xhtmlNamespaceURI); +DEFINE_GLOBAL(QualifiedName, onorientationchangeAttr, nullAtom, "onorientationchange", xhtmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, onpagehideAttr, nullAtom, "onpagehide", xhtmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, onpageshowAttr, nullAtom, "onpageshow", xhtmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, onpasteAttr, nullAtom, "onpaste", xhtmlNamespaceURI); @@ -702,6 +703,7 @@ WebCore::QualifiedName** getHTMLAttrs(size_t* size) (WebCore::QualifiedName*)&onmousewheelAttr, (WebCore::QualifiedName*)&onofflineAttr, (WebCore::QualifiedName*)&ononlineAttr, + (WebCore::QualifiedName*)&onorientationchangeAttr, (WebCore::QualifiedName*)&onpagehideAttr, (WebCore::QualifiedName*)&onpageshowAttr, (WebCore::QualifiedName*)&onpasteAttr, @@ -786,7 +788,7 @@ WebCore::QualifiedName** getHTMLAttrs(size_t* size) (WebCore::QualifiedName*)&widthAttr, (WebCore::QualifiedName*)&wrapAttr, }; - *size = 246; + *size = 247; return HTMLAttr; } @@ -1206,6 +1208,7 @@ void init() const char *onmousewheelAttrString = "onmousewheel"; const char *onofflineAttrString = "onoffline"; const char *ononlineAttrString = "ononline"; + const char *onorientationchangeAttrString = "onorientationchange"; const char *onpagehideAttrString = "onpagehide"; const char *onpageshowAttrString = "onpageshow"; const char *onpasteAttrString = "onpaste"; @@ -1452,6 +1455,7 @@ void init() new ((void*)&onmousewheelAttr) QualifiedName(nullAtom, onmousewheelAttrString, nullAtom); new ((void*)&onofflineAttr) QualifiedName(nullAtom, onofflineAttrString, nullAtom); new ((void*)&ononlineAttr) QualifiedName(nullAtom, ononlineAttrString, nullAtom); + new ((void*)&onorientationchangeAttr) QualifiedName(nullAtom, onorientationchangeAttrString, nullAtom); new ((void*)&onpagehideAttr) QualifiedName(nullAtom, onpagehideAttrString, nullAtom); new ((void*)&onpageshowAttr) QualifiedName(nullAtom, onpageshowAttrString, nullAtom); new ((void*)&onpasteAttr) QualifiedName(nullAtom, onpasteAttrString, nullAtom); diff --git a/src/3rdparty/webkit/WebCore/generated/HTMLNames.h b/src/3rdparty/webkit/WebCore/generated/HTMLNames.h index a7fb532..d7d327f 100644 --- a/src/3rdparty/webkit/WebCore/generated/HTMLNames.h +++ b/src/3rdparty/webkit/WebCore/generated/HTMLNames.h @@ -322,6 +322,7 @@ extern const WebCore::QualifiedName onmouseupAttr; extern const WebCore::QualifiedName onmousewheelAttr; extern const WebCore::QualifiedName onofflineAttr; extern const WebCore::QualifiedName ononlineAttr; +extern const WebCore::QualifiedName onorientationchangeAttr; extern const WebCore::QualifiedName onpagehideAttr; extern const WebCore::QualifiedName onpageshowAttr; extern const WebCore::QualifiedName onpasteAttr; diff --git a/src/3rdparty/webkit/WebCore/generated/JSAbstractWorker.cpp b/src/3rdparty/webkit/WebCore/generated/JSAbstractWorker.cpp index 7c6452d..28e127d 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSAbstractWorker.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSAbstractWorker.cpp @@ -31,6 +31,7 @@ #include "JSDOMGlobalObject.h" #include "JSEvent.h" #include "JSEventListener.h" +#include "RegisteredEventListener.h" #include <runtime/Error.h> #include <wtf/GetPtr.h> @@ -144,7 +145,14 @@ JSAbstractWorker::JSAbstractWorker(PassRefPtr<Structure> structure, JSDOMGlobalO JSAbstractWorker::~JSAbstractWorker() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); +} + +void JSAbstractWorker::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + impl()->markEventListeners(markStack); } JSObject* JSAbstractWorker::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSBarInfo.cpp b/src/3rdparty/webkit/WebCore/generated/JSBarInfo.cpp index a01207f..6ebd59c 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSBarInfo.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSBarInfo.cpp @@ -76,7 +76,7 @@ JSBarInfo::JSBarInfo(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSBarInfo::~JSBarInfo() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSBarInfo::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCSSRule.cpp b/src/3rdparty/webkit/WebCore/generated/JSCSSRule.cpp index 329c7d6..fe8476b 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCSSRule.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCSSRule.cpp @@ -159,7 +159,7 @@ JSCSSRule::JSCSSRule(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSCSSRule::~JSCSSRule() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCSSRule::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCSSRuleList.cpp b/src/3rdparty/webkit/WebCore/generated/JSCSSRuleList.cpp index 3a71cc3..7e62e27 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCSSRuleList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCSSRuleList.cpp @@ -137,7 +137,7 @@ JSCSSRuleList::JSCSSRuleList(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSCSSRuleList::~JSCSSRuleList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCSSRuleList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCSSStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/generated/JSCSSStyleDeclaration.cpp index d0ccb9b..1a6eeb9 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCSSStyleDeclaration.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCSSStyleDeclaration.cpp @@ -151,7 +151,7 @@ JSCSSStyleDeclaration::JSCSSStyleDeclaration(PassRefPtr<Structure> structure, JS JSCSSStyleDeclaration::~JSCSSStyleDeclaration() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCSSStyleDeclaration::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCSSValue.cpp b/src/3rdparty/webkit/WebCore/generated/JSCSSValue.cpp index 58c0990..b5152cb 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCSSValue.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCSSValue.cpp @@ -142,7 +142,7 @@ JSCSSValue::JSCSSValue(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSCSSValue::~JSCSSValue() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCSSValue::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCSSVariablesDeclaration.cpp b/src/3rdparty/webkit/WebCore/generated/JSCSSVariablesDeclaration.cpp index 419ba7d..8e2ef47 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCSSVariablesDeclaration.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCSSVariablesDeclaration.cpp @@ -144,7 +144,7 @@ JSCSSVariablesDeclaration::JSCSSVariablesDeclaration(PassRefPtr<Structure> struc JSCSSVariablesDeclaration::~JSCSSVariablesDeclaration() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCSSVariablesDeclaration::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasArray.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasArray.cpp index 685bd6d..2331bba 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasArray.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasArray.cpp @@ -93,7 +93,7 @@ JSCanvasArray::JSCanvasArray(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSCanvasArray::~JSCanvasArray() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCanvasArray::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasArrayBuffer.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasArrayBuffer.cpp index 644e3ed..b8a9406 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasArrayBuffer.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasArrayBuffer.cpp @@ -80,7 +80,7 @@ JSCanvasArrayBuffer::JSCanvasArrayBuffer(PassRefPtr<Structure> structure, JSDOMG JSCanvasArrayBuffer::~JSCanvasArrayBuffer() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCanvasArrayBuffer::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasGradient.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasGradient.cpp index 70f71bc..aec7049 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasGradient.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasGradient.cpp @@ -74,7 +74,7 @@ JSCanvasGradient::JSCanvasGradient(PassRefPtr<Structure> structure, JSDOMGlobalO JSCanvasGradient::~JSCanvasGradient() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCanvasGradient::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasPattern.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasPattern.cpp index c806e5d..27db344 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasPattern.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasPattern.cpp @@ -61,7 +61,7 @@ JSCanvasPattern::JSCanvasPattern(PassRefPtr<Structure> structure, JSDOMGlobalObj JSCanvasPattern::~JSCanvasPattern() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCanvasPattern::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext.cpp index aedc360..9bbdff5 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext.cpp @@ -123,7 +123,7 @@ JSCanvasRenderingContext::JSCanvasRenderingContext(PassRefPtr<Structure> structu JSCanvasRenderingContext::~JSCanvasRenderingContext() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCanvasRenderingContext::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSClientRect.cpp b/src/3rdparty/webkit/WebCore/generated/JSClientRect.cpp index ea5d079..a7f4de1 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSClientRect.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSClientRect.cpp @@ -127,7 +127,7 @@ JSClientRect::JSClientRect(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSClientRect::~JSClientRect() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSClientRect::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSClientRectList.cpp b/src/3rdparty/webkit/WebCore/generated/JSClientRectList.cpp index e840f61..1373327 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSClientRectList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSClientRectList.cpp @@ -138,7 +138,7 @@ JSClientRectList::JSClientRectList(PassRefPtr<Structure> structure, JSDOMGlobalO JSClientRectList::~JSClientRectList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSClientRectList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSClipboard.cpp b/src/3rdparty/webkit/WebCore/generated/JSClipboard.cpp index 708c546..08b4630 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSClipboard.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSClipboard.cpp @@ -142,7 +142,7 @@ JSClipboard::JSClipboard(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSClipboard::~JSClipboard() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSClipboard::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSConsole.cpp b/src/3rdparty/webkit/WebCore/generated/JSConsole.cpp index 1f8c6d8..897401d 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSConsole.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSConsole.cpp @@ -104,7 +104,7 @@ JSConsole::JSConsole(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSConsole::~JSConsole() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSConsole::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCoordinates.cpp b/src/3rdparty/webkit/WebCore/generated/JSCoordinates.cpp index 21efdc8..68636b7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCoordinates.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCoordinates.cpp @@ -83,7 +83,7 @@ JSCoordinates::JSCoordinates(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSCoordinates::~JSCoordinates() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCoordinates::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCounter.cpp b/src/3rdparty/webkit/WebCore/generated/JSCounter.cpp index d7bc5f1..edd7ead 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCounter.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCounter.cpp @@ -125,7 +125,7 @@ JSCounter::JSCounter(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSCounter::~JSCounter() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSCounter::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMApplicationCache.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMApplicationCache.cpp index e28b6ec..d2b052b 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMApplicationCache.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMApplicationCache.cpp @@ -31,6 +31,7 @@ #include "JSDOMGlobalObject.h" #include "JSEvent.h" #include "JSEventListener.h" +#include "RegisteredEventListener.h" #include <runtime/Error.h> #include <runtime/JSNumberCell.h> #include <wtf/GetPtr.h> @@ -116,7 +117,14 @@ JSDOMApplicationCache::JSDOMApplicationCache(PassRefPtr<Structure> structure, JS JSDOMApplicationCache::~JSDOMApplicationCache() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); +} + +void JSDOMApplicationCache::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + impl()->markEventListeners(markStack); } JSObject* JSDOMApplicationCache::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMCoreException.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMCoreException.cpp index 94df8dd..fbca8b2 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMCoreException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMCoreException.cpp @@ -182,7 +182,7 @@ JSDOMCoreException::JSDOMCoreException(PassRefPtr<Structure> structure, JSDOMGlo JSDOMCoreException::~JSDOMCoreException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDOMCoreException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMImplementation.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMImplementation.cpp index 27eb530..2e678bb 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMImplementation.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMImplementation.cpp @@ -145,7 +145,7 @@ JSDOMImplementation::JSDOMImplementation(PassRefPtr<Structure> structure, JSDOMG JSDOMImplementation::~JSDOMImplementation() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDOMImplementation::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMParser.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMParser.cpp index 8ff4a03..1880607 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMParser.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMParser.cpp @@ -144,7 +144,7 @@ JSDOMParser::JSDOMParser(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSDOMParser::~JSDOMParser() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDOMParser::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMSelection.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMSelection.cpp index daf65df..88ddfc1 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMSelection.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMSelection.cpp @@ -119,7 +119,7 @@ JSDOMSelection::JSDOMSelection(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSDOMSelection::~JSDOMSelection() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDOMSelection::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp index 414a1bb..8e85b60 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp @@ -214,6 +214,7 @@ #include "JSWebKitCSSTransformValue.h" #include "JSWebKitPoint.h" #include "JSWebKitTransitionEvent.h" +#include "JSWebSocket.h" #include "JSWheelEvent.h" #include "JSWorker.h" #include "JSXMLHttpRequest.h" @@ -243,7 +244,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSDOMWindow); /* Hash table */ -static const HashTableValue JSDOMWindowTableValues[293] = +static const HashTableValue JSDOMWindowTableValues[294] = { { "screen", DontDelete|ReadOnly, (intptr_t)jsDOMWindowScreen, (intptr_t)0 }, { "history", DontDelete|ReadOnly, (intptr_t)jsDOMWindowHistory, (intptr_t)0 }, @@ -531,6 +532,7 @@ static const HashTableValue JSDOMWindowTableValues[293] = { "MessageChannel", DontDelete, (intptr_t)jsDOMWindowMessageChannelConstructor, (intptr_t)setJSDOMWindowMessageChannelConstructor }, { "Worker", DontDelete, (intptr_t)jsDOMWindowWorkerConstructor, (intptr_t)setJSDOMWindowWorkerConstructor }, { "SharedWorker", DontDelete, (intptr_t)jsDOMWindowSharedWorkerConstructor, (intptr_t)setJSDOMWindowSharedWorkerConstructor }, + { "WebSocket", DontDelete, (intptr_t)jsDOMWindowWebSocketConstructor, (intptr_t)setJSDOMWindowWebSocketConstructor }, { "Plugin", DontDelete, (intptr_t)jsDOMWindowPluginConstructor, (intptr_t)setJSDOMWindowPluginConstructor }, { "PluginArray", DontDelete, (intptr_t)jsDOMWindowPluginArrayConstructor, (intptr_t)setJSDOMWindowPluginArrayConstructor }, { "MimeType", DontDelete, (intptr_t)jsDOMWindowMimeTypeConstructor, (intptr_t)setJSDOMWindowMimeTypeConstructor }, @@ -578,7 +580,7 @@ static JSC_CONST_HASHTABLE HashTable JSDOMWindowTable = #if ENABLE(PERFECT_HASH_SIZE) { 65535, JSDOMWindowTableValues, 0 }; #else - { 1067, 1023, JSDOMWindowTableValues, 0 }; + { 1068, 1023, JSDOMWindowTableValues, 0 }; #endif /* Hash table for prototype */ @@ -657,7 +659,8 @@ JSDOMWindow::JSDOMWindow(PassRefPtr<Structure> structure, PassRefPtr<DOMWindow> JSDOMWindow::~JSDOMWindow() { - invalidateEventListeners(impl()->eventListeners()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSValue jsDOMWindowScreen(ExecState* exec, const Identifier&, const PropertySlot& slot) @@ -3239,6 +3242,14 @@ JSValue jsDOMWindowSharedWorkerConstructor(ExecState* exec, const Identifier&, c return castedThis->sharedWorker(exec); } +JSValue jsDOMWindowWebSocketConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) +{ + JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); + if (!castedThis->allowsAccessFrom(exec)) + return jsUndefined(); + return castedThis->webSocket(exec); +} + JSValue jsDOMWindowPluginConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); @@ -5610,6 +5621,14 @@ void setJSDOMWindowSharedWorkerConstructor(ExecState* exec, JSObject* thisObject static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "SharedWorker"), value); } +void setJSDOMWindowWebSocketConstructor(ExecState* exec, JSObject* thisObject, JSValue value) +{ + if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) + return; + // Shadowing a built-in constructor + static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "WebSocket"), value); +} + void setJSDOMWindowPluginConstructor(ExecState* exec, JSObject* thisObject, JSValue value) { if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h index 5b1b58e..5c723f1 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h @@ -50,10 +50,11 @@ public: virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); + virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const; - virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); - virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes); virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); @@ -80,6 +81,7 @@ public: JSC::JSValue messageChannel(JSC::ExecState*) const; JSC::JSValue worker(JSC::ExecState*) const; JSC::JSValue sharedWorker(JSC::ExecState*) const; + JSC::JSValue webSocket(JSC::ExecState*) const; JSC::JSValue audio(JSC::ExecState*) const; // Custom functions @@ -666,6 +668,8 @@ JSC::JSValue jsDOMWindowWorkerConstructor(JSC::ExecState*, const JSC::Identifier void setJSDOMWindowWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowSharedWorkerConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowSharedWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); +JSC::JSValue jsDOMWindowWebSocketConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); +void setJSDOMWindowWebSocketConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowPluginConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginArrayConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/generated/JSDataGridColumn.cpp b/src/3rdparty/webkit/WebCore/generated/JSDataGridColumn.cpp index 59eafb1..c0187fb 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDataGridColumn.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDataGridColumn.cpp @@ -154,7 +154,7 @@ JSDataGridColumn::JSDataGridColumn(PassRefPtr<Structure> structure, JSDOMGlobalO JSDataGridColumn::~JSDataGridColumn() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDataGridColumn::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDataGridColumnList.cpp b/src/3rdparty/webkit/WebCore/generated/JSDataGridColumnList.cpp index 2ec302a..10c8813 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDataGridColumnList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDataGridColumnList.cpp @@ -148,7 +148,7 @@ JSDataGridColumnList::JSDataGridColumnList(PassRefPtr<Structure> structure, JSDO JSDataGridColumnList::~JSDataGridColumnList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDataGridColumnList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDatabase.cpp b/src/3rdparty/webkit/WebCore/generated/JSDatabase.cpp index 16b0888..cb2dc3f 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDatabase.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDatabase.cpp @@ -95,7 +95,7 @@ JSDatabase::JSDatabase(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSDatabase::~JSDatabase() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSDatabase::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDedicatedWorkerContext.h b/src/3rdparty/webkit/WebCore/generated/JSDedicatedWorkerContext.h index d6caa8d..d513c8f 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDedicatedWorkerContext.h +++ b/src/3rdparty/webkit/WebCore/generated/JSDedicatedWorkerContext.h @@ -45,8 +45,6 @@ public: return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } - virtual void markChildren(JSC::MarkStack&); - // Custom functions JSC::JSValue postMessage(JSC::ExecState*, const JSC::ArgList&); @@ -68,7 +66,7 @@ public: virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::HasDefaultMark)); } JSDedicatedWorkerContextPrototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { } }; diff --git a/src/3rdparty/webkit/WebCore/generated/JSEvent.cpp b/src/3rdparty/webkit/WebCore/generated/JSEvent.cpp index 9d9b7f2..833b5a0 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSEvent.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSEvent.cpp @@ -196,7 +196,7 @@ JSEvent::JSEvent(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObjec JSEvent::~JSEvent() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSEvent::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSEventException.cpp b/src/3rdparty/webkit/WebCore/generated/JSEventException.cpp index df2cebc..9044090 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSEventException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSEventException.cpp @@ -148,7 +148,7 @@ JSEventException::JSEventException(PassRefPtr<Structure> structure, JSDOMGlobalO JSEventException::~JSEventException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSEventException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSEventSource.cpp b/src/3rdparty/webkit/WebCore/generated/JSEventSource.cpp index 8fe292b..69471ee 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSEventSource.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSEventSource.cpp @@ -32,6 +32,7 @@ #include "JSEvent.h" #include "JSEventListener.h" #include "KURL.h" +#include "RegisteredEventListener.h" #include <runtime/Error.h> #include <runtime/JSNumberCell.h> #include <runtime/JSString.h> @@ -118,7 +119,14 @@ JSEventSource::JSEventSource(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSEventSource::~JSEventSource() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); +} + +void JSEventSource::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + impl()->markEventListeners(markStack); } JSObject* JSEventSource::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSFile.cpp b/src/3rdparty/webkit/WebCore/generated/JSFile.cpp index 5fa637e..a426abf 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSFile.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSFile.cpp @@ -125,7 +125,7 @@ JSFile::JSFile(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, JSFile::~JSFile() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSFile::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSFileList.cpp b/src/3rdparty/webkit/WebCore/generated/JSFileList.cpp index 5fb8b0c..da2ed09 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSFileList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSFileList.cpp @@ -138,7 +138,7 @@ JSFileList::JSFileList(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSFileList::~JSFileList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSFileList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSGeolocation.cpp b/src/3rdparty/webkit/WebCore/generated/JSGeolocation.cpp index 7a1e5f0..e5d4526 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSGeolocation.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSGeolocation.cpp @@ -92,7 +92,7 @@ JSGeolocation::JSGeolocation(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSGeolocation::~JSGeolocation() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSGeolocation::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSGeoposition.cpp b/src/3rdparty/webkit/WebCore/generated/JSGeoposition.cpp index 400e0d4..8219fb2 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSGeoposition.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSGeoposition.cpp @@ -80,7 +80,7 @@ JSGeoposition::JSGeoposition(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSGeoposition::~JSGeoposition() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSGeoposition::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSHTMLCollection.cpp b/src/3rdparty/webkit/WebCore/generated/JSHTMLCollection.cpp index b93fb61..30defc0 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSHTMLCollection.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSHTMLCollection.cpp @@ -143,7 +143,7 @@ JSHTMLCollection::JSHTMLCollection(PassRefPtr<Structure> structure, JSDOMGlobalO JSHTMLCollection::~JSHTMLCollection() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSHTMLCollection::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.cpp b/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.cpp index ffe9716..be123db 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.cpp @@ -41,7 +41,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSHTMLTextAreaElement); /* Hash table */ -static const HashTableValue JSHTMLTextAreaElementTableValues[20] = +static const HashTableValue JSHTMLTextAreaElementTableValues[21] = { { "defaultValue", DontDelete, (intptr_t)jsHTMLTextAreaElementDefaultValue, (intptr_t)setJSHTMLTextAreaElementDefaultValue }, { "form", DontDelete|ReadOnly, (intptr_t)jsHTMLTextAreaElementForm, (intptr_t)0 }, @@ -50,6 +50,7 @@ static const HashTableValue JSHTMLTextAreaElementTableValues[20] = { "cols", DontDelete, (intptr_t)jsHTMLTextAreaElementCols, (intptr_t)setJSHTMLTextAreaElementCols }, { "disabled", DontDelete, (intptr_t)jsHTMLTextAreaElementDisabled, (intptr_t)setJSHTMLTextAreaElementDisabled }, { "autofocus", DontDelete, (intptr_t)jsHTMLTextAreaElementAutofocus, (intptr_t)setJSHTMLTextAreaElementAutofocus }, + { "maxLength", DontDelete, (intptr_t)jsHTMLTextAreaElementMaxLength, (intptr_t)setJSHTMLTextAreaElementMaxLength }, { "name", DontDelete, (intptr_t)jsHTMLTextAreaElementName, (intptr_t)setJSHTMLTextAreaElementName }, { "placeholder", DontDelete, (intptr_t)jsHTMLTextAreaElementPlaceholder, (intptr_t)setJSHTMLTextAreaElementPlaceholder }, { "readOnly", DontDelete, (intptr_t)jsHTMLTextAreaElementReadOnly, (intptr_t)setJSHTMLTextAreaElementReadOnly }, @@ -229,6 +230,14 @@ JSValue jsHTMLTextAreaElementAutofocus(ExecState* exec, const Identifier&, const return jsBoolean(imp->autofocus()); } +JSValue jsHTMLTextAreaElementMaxLength(ExecState* exec, const Identifier&, const PropertySlot& slot) +{ + JSHTMLTextAreaElement* castedThis = static_cast<JSHTMLTextAreaElement*>(asObject(slot.slotBase())); + UNUSED_PARAM(exec); + HTMLTextAreaElement* imp = static_cast<HTMLTextAreaElement*>(castedThis->impl()); + return jsNumber(exec, imp->maxLength()); +} + JSValue jsHTMLTextAreaElementName(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSHTMLTextAreaElement* castedThis = static_cast<JSHTMLTextAreaElement*>(asObject(slot.slotBase())); @@ -357,6 +366,12 @@ void setJSHTMLTextAreaElementAutofocus(ExecState* exec, JSObject* thisObject, JS imp->setAutofocus(value.toBoolean(exec)); } +void setJSHTMLTextAreaElementMaxLength(ExecState* exec, JSObject* thisObject, JSValue value) +{ + HTMLTextAreaElement* imp = static_cast<HTMLTextAreaElement*>(static_cast<JSHTMLTextAreaElement*>(thisObject)->impl()); + imp->setMaxLength(value.toInt32(exec)); +} + void setJSHTMLTextAreaElementName(ExecState* exec, JSObject* thisObject, JSValue value) { HTMLTextAreaElement* imp = static_cast<HTMLTextAreaElement*>(static_cast<JSHTMLTextAreaElement*>(thisObject)->impl()); diff --git a/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.h b/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.h index 313af9f..0df320e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.h +++ b/src/3rdparty/webkit/WebCore/generated/JSHTMLTextAreaElement.h @@ -82,6 +82,8 @@ JSC::JSValue jsHTMLTextAreaElementDisabled(JSC::ExecState*, const JSC::Identifie void setJSHTMLTextAreaElementDisabled(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsHTMLTextAreaElementAutofocus(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSHTMLTextAreaElementAutofocus(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); +JSC::JSValue jsHTMLTextAreaElementMaxLength(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); +void setJSHTMLTextAreaElementMaxLength(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsHTMLTextAreaElementName(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSHTMLTextAreaElementName(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsHTMLTextAreaElementPlaceholder(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/generated/JSHistory.cpp b/src/3rdparty/webkit/WebCore/generated/JSHistory.cpp index d7c2b04..2d6e7d4 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSHistory.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSHistory.cpp @@ -92,7 +92,7 @@ JSHistory::JSHistory(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSHistory::~JSHistory() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSHistory::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSImageData.cpp b/src/3rdparty/webkit/WebCore/generated/JSImageData.cpp index b918220..796c592 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSImageData.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSImageData.cpp @@ -123,7 +123,7 @@ JSImageData::JSImageData(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSImageData::~JSImageData() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSImageData::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.cpp b/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.cpp index c77185c..77b4b7c 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.cpp @@ -96,7 +96,7 @@ bool JSInspectorBackendConstructor::getOwnPropertyDescriptor(ExecState* exec, co /* Hash table for prototype */ -static const HashTableValue JSInspectorBackendPrototypeTableValues[66] = +static const HashTableValue JSInspectorBackendPrototypeTableValues[69] = { { "hideDOMNodeHighlight", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionHideDOMNodeHighlight, (intptr_t)0 }, { "highlightDOMNode", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionHighlightDOMNode, (intptr_t)1 }, @@ -163,6 +163,9 @@ static const HashTableValue JSInspectorBackendPrototypeTableValues[66] = { "addNodesToSearchResult", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionAddNodesToSearchResult, (intptr_t)1 }, { "selectDatabase", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionSelectDatabase, (intptr_t)1 }, { "selectDOMStorage", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionSelectDOMStorage, (intptr_t)1 }, + { "getDOMStorageEntries", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionGetDOMStorageEntries, (intptr_t)2 }, + { "setDOMStorageItem", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionSetDOMStorageItem, (intptr_t)4 }, + { "removeDOMStorageItem", DontDelete|Function, (intptr_t)jsInspectorBackendPrototypeFunctionRemoveDOMStorageItem, (intptr_t)3 }, { 0, 0, 0, 0 } }; @@ -200,7 +203,7 @@ JSInspectorBackend::JSInspectorBackend(PassRefPtr<Structure> structure, JSDOMGlo JSInspectorBackend::~JSInspectorBackend() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSInspectorBackend::createPrototype(ExecState* exec, JSGlobalObject* globalObject) @@ -1019,6 +1022,51 @@ JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionSelectDOMStorage(ExecSt return castedThisObj->selectDOMStorage(exec, args); } +JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionGetDOMStorageEntries(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) +{ + UNUSED_PARAM(args); + if (!thisValue.inherits(&JSInspectorBackend::s_info)) + return throwError(exec, TypeError); + JSInspectorBackend* castedThisObj = static_cast<JSInspectorBackend*>(asObject(thisValue)); + InspectorBackend* imp = static_cast<InspectorBackend*>(castedThisObj->impl()); + int callId = args.at(0).toInt32(exec); + int storageId = args.at(1).toInt32(exec); + + imp->getDOMStorageEntries(callId, storageId); + return jsUndefined(); +} + +JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionSetDOMStorageItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) +{ + UNUSED_PARAM(args); + if (!thisValue.inherits(&JSInspectorBackend::s_info)) + return throwError(exec, TypeError); + JSInspectorBackend* castedThisObj = static_cast<JSInspectorBackend*>(asObject(thisValue)); + InspectorBackend* imp = static_cast<InspectorBackend*>(castedThisObj->impl()); + int callId = args.at(0).toInt32(exec); + int storageId = args.at(1).toInt32(exec); + const UString& key = args.at(2).toString(exec); + const UString& value = args.at(3).toString(exec); + + imp->setDOMStorageItem(callId, storageId, key, value); + return jsUndefined(); +} + +JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionRemoveDOMStorageItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) +{ + UNUSED_PARAM(args); + if (!thisValue.inherits(&JSInspectorBackend::s_info)) + return throwError(exec, TypeError); + JSInspectorBackend* castedThisObj = static_cast<JSInspectorBackend*>(asObject(thisValue)); + InspectorBackend* imp = static_cast<InspectorBackend*>(castedThisObj->impl()); + int callId = args.at(0).toInt32(exec); + int storageId = args.at(1).toInt32(exec); + const UString& key = args.at(2).toString(exec); + + imp->removeDOMStorageItem(callId, storageId, key); + return jsUndefined(); +} + JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, InspectorBackend* object) { return getDOMObjectWrapper<JSInspectorBackend>(exec, globalObject, object); diff --git a/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.h b/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.h index 102a5b4..fec9031 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.h +++ b/src/3rdparty/webkit/WebCore/generated/JSInspectorBackend.h @@ -155,6 +155,9 @@ JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionPushNodePathToFron JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionAddNodesToSearchResult(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionSelectDatabase(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionSelectDOMStorage(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionGetDOMStorageEntries(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionSetDOMStorageItem(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +JSC::JSValue JSC_HOST_CALL jsInspectorBackendPrototypeFunctionRemoveDOMStorageItem(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); // Attributes JSC::JSValue jsInspectorBackendConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/generated/JSJavaScriptCallFrame.cpp b/src/3rdparty/webkit/WebCore/generated/JSJavaScriptCallFrame.cpp index 9ec80b0..212ed59 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSJavaScriptCallFrame.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSJavaScriptCallFrame.cpp @@ -101,7 +101,7 @@ JSJavaScriptCallFrame::JSJavaScriptCallFrame(PassRefPtr<Structure> structure, JS JSJavaScriptCallFrame::~JSJavaScriptCallFrame() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSJavaScriptCallFrame::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSLocation.cpp b/src/3rdparty/webkit/WebCore/generated/JSLocation.cpp index 9df3a4d..0889e16 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSLocation.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSLocation.cpp @@ -108,7 +108,7 @@ JSLocation::JSLocation(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSLocation::~JSLocation() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSLocation::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSLocation.h b/src/3rdparty/webkit/WebCore/generated/JSLocation.h index 54b41ce..8db2969 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSLocation.h +++ b/src/3rdparty/webkit/WebCore/generated/JSLocation.h @@ -52,7 +52,7 @@ public: virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); // Custom attributes void setHref(JSC::ExecState*, JSC::JSValue); @@ -92,7 +92,7 @@ public: } virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); bool putDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); - virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); JSLocationPrototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { } }; diff --git a/src/3rdparty/webkit/WebCore/generated/JSMedia.cpp b/src/3rdparty/webkit/WebCore/generated/JSMedia.cpp index 26dffa8..8106ab4 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMedia.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMedia.cpp @@ -135,7 +135,7 @@ JSMedia::JSMedia(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObjec JSMedia::~JSMedia() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMedia::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMediaError.cpp b/src/3rdparty/webkit/WebCore/generated/JSMediaError.cpp index 5a906ae..43640f3 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMediaError.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMediaError.cpp @@ -143,7 +143,7 @@ JSMediaError::JSMediaError(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSMediaError::~JSMediaError() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMediaError::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMediaList.cpp b/src/3rdparty/webkit/WebCore/generated/JSMediaList.cpp index 8c5e097..04d30bb 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMediaList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMediaList.cpp @@ -139,7 +139,7 @@ JSMediaList::JSMediaList(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSMediaList::~JSMediaList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMediaList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMessageChannel.cpp b/src/3rdparty/webkit/WebCore/generated/JSMessageChannel.cpp index accf6e3..d851688 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMessageChannel.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMessageChannel.cpp @@ -87,7 +87,7 @@ JSMessageChannel::JSMessageChannel(PassRefPtr<Structure> structure, JSDOMGlobalO JSMessageChannel::~JSMessageChannel() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMessageChannel::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMessagePort.cpp b/src/3rdparty/webkit/WebCore/generated/JSMessagePort.cpp index 7cbcc88..a532d51 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMessagePort.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMessagePort.cpp @@ -29,6 +29,7 @@ #include "JSEventListener.h" #include "MessagePort.h" #include "PlatformString.h" +#include "RegisteredEventListener.h" #include <runtime/Error.h> #include <wtf/GetPtr.h> @@ -153,7 +154,8 @@ JSMessagePort::JSMessagePort(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSMessagePort::~JSMessagePort() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMessagePort::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMimeType.cpp b/src/3rdparty/webkit/WebCore/generated/JSMimeType.cpp index 0857400..458d7d7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMimeType.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMimeType.cpp @@ -128,7 +128,7 @@ JSMimeType::JSMimeType(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSMimeType::~JSMimeType() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMimeType::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSMimeTypeArray.cpp b/src/3rdparty/webkit/WebCore/generated/JSMimeTypeArray.cpp index 5cc3fd4..79f7bce 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSMimeTypeArray.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSMimeTypeArray.cpp @@ -139,7 +139,7 @@ JSMimeTypeArray::JSMimeTypeArray(PassRefPtr<Structure> structure, JSDOMGlobalObj JSMimeTypeArray::~JSMimeTypeArray() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSMimeTypeArray::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNamedNodeMap.cpp b/src/3rdparty/webkit/WebCore/generated/JSNamedNodeMap.cpp index 71d3cef..a9b9e44 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNamedNodeMap.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNamedNodeMap.cpp @@ -144,7 +144,7 @@ JSNamedNodeMap::JSNamedNodeMap(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSNamedNodeMap::~JSNamedNodeMap() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSNamedNodeMap::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNavigator.cpp b/src/3rdparty/webkit/WebCore/generated/JSNavigator.cpp index bf18b74..cdb2d38 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNavigator.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNavigator.cpp @@ -108,7 +108,7 @@ JSNavigator::JSNavigator(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSNavigator::~JSNavigator() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSNavigator::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNode.cpp b/src/3rdparty/webkit/WebCore/generated/JSNode.cpp index 59f6004..beb059e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNode.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNode.cpp @@ -217,8 +217,8 @@ JSNode::JSNode(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, JSNode::~JSNode() { - invalidateEventListeners(m_impl->eventListeners()); - forgetDOMNode(m_impl->document(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMNode(impl()->document(), impl()); } JSObject* JSNode::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNodeFilter.cpp b/src/3rdparty/webkit/WebCore/generated/JSNodeFilter.cpp index e4c50ba..37c4367 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNodeFilter.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNodeFilter.cpp @@ -164,7 +164,7 @@ JSNodeFilter::JSNodeFilter(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSNodeFilter::~JSNodeFilter() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSNodeFilter::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNodeIterator.cpp b/src/3rdparty/webkit/WebCore/generated/JSNodeIterator.cpp index 0f4167d..324be0f 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNodeIterator.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNodeIterator.cpp @@ -145,7 +145,7 @@ JSNodeIterator::JSNodeIterator(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSNodeIterator::~JSNodeIterator() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSNodeIterator::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSNodeList.cpp b/src/3rdparty/webkit/WebCore/generated/JSNodeList.cpp index 892ba5b..fe6f6ca 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSNodeList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSNodeList.cpp @@ -139,7 +139,7 @@ JSNodeList::JSNodeList(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSNodeList::~JSNodeList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSNodeList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSPlugin.cpp b/src/3rdparty/webkit/WebCore/generated/JSPlugin.cpp index e23dc5a..1416a74 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSPlugin.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSPlugin.cpp @@ -144,7 +144,7 @@ JSPlugin::JSPlugin(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObj JSPlugin::~JSPlugin() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSPlugin::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSPluginArray.cpp b/src/3rdparty/webkit/WebCore/generated/JSPluginArray.cpp index 9f46e08..436b924 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSPluginArray.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSPluginArray.cpp @@ -140,7 +140,7 @@ JSPluginArray::JSPluginArray(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSPluginArray::~JSPluginArray() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSPluginArray::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSPositionError.cpp b/src/3rdparty/webkit/WebCore/generated/JSPositionError.cpp index 03c0ba3..234481f 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSPositionError.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSPositionError.cpp @@ -143,7 +143,7 @@ JSPositionError::JSPositionError(PassRefPtr<Structure> structure, JSDOMGlobalObj JSPositionError::~JSPositionError() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSPositionError::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSRGBColor.cpp b/src/3rdparty/webkit/WebCore/generated/JSRGBColor.cpp index f3b1a35..b0bf6b4 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSRGBColor.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSRGBColor.cpp @@ -125,7 +125,7 @@ JSRGBColor::JSRGBColor(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSRGBColor::~JSRGBColor() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSRGBColor::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSRange.cpp b/src/3rdparty/webkit/WebCore/generated/JSRange.cpp index dffeb8a..9968a29 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSRange.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSRange.cpp @@ -185,7 +185,7 @@ JSRange::JSRange(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObjec JSRange::~JSRange() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSRange::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSRangeException.cpp b/src/3rdparty/webkit/WebCore/generated/JSRangeException.cpp index 1ef3ced..29db9c0 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSRangeException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSRangeException.cpp @@ -142,7 +142,7 @@ JSRangeException::JSRangeException(PassRefPtr<Structure> structure, JSDOMGlobalO JSRangeException::~JSRangeException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSRangeException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSRect.cpp b/src/3rdparty/webkit/WebCore/generated/JSRect.cpp index b717102..df9089d 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSRect.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSRect.cpp @@ -126,7 +126,7 @@ JSRect::JSRect(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, JSRect::~JSRect() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSRect::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSQLError.cpp b/src/3rdparty/webkit/WebCore/generated/JSSQLError.cpp index a004498..acab07d 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSQLError.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSQLError.cpp @@ -83,7 +83,7 @@ JSSQLError::JSSQLError(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSSQLError::~JSSQLError() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSQLError::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSQLResultSet.cpp b/src/3rdparty/webkit/WebCore/generated/JSSQLResultSet.cpp index 7218490..d12399a 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSQLResultSet.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSQLResultSet.cpp @@ -84,7 +84,7 @@ JSSQLResultSet::JSSQLResultSet(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSSQLResultSet::~JSSQLResultSet() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSQLResultSet::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSQLResultSetRowList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSQLResultSetRowList.cpp index 7fa87e5..6253b97 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSQLResultSetRowList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSQLResultSetRowList.cpp @@ -92,7 +92,7 @@ JSSQLResultSetRowList::JSSQLResultSetRowList(PassRefPtr<Structure> structure, JS JSSQLResultSetRowList::~JSSQLResultSetRowList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSQLResultSetRowList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSQLTransaction.cpp b/src/3rdparty/webkit/WebCore/generated/JSSQLTransaction.cpp index 485cda6..00f5649 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSQLTransaction.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSQLTransaction.cpp @@ -76,7 +76,7 @@ JSSQLTransaction::JSSQLTransaction(PassRefPtr<Structure> structure, JSDOMGlobalO JSSQLTransaction::~JSSQLTransaction() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSQLTransaction::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAngle.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAngle.cpp index 1551f8e..22d0740 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAngle.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAngle.cpp @@ -153,7 +153,7 @@ JSSVGAngle::JSSVGAngle(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSSVGAngle::~JSSVGAngle() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAngle::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedAngle.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedAngle.cpp index 3375a94..f54fda9 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedAngle.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedAngle.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedAngle::JSSVGAnimatedAngle(PassRefPtr<Structure> structure, JSDOMGlo JSSVGAnimatedAngle::~JSSVGAnimatedAngle() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedAngle::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedBoolean.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedBoolean.cpp index 29d0622..12c1822 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedBoolean.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedBoolean.cpp @@ -79,7 +79,7 @@ JSSVGAnimatedBoolean::JSSVGAnimatedBoolean(PassRefPtr<Structure> structure, JSDO JSSVGAnimatedBoolean::~JSSVGAnimatedBoolean() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedBoolean::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedEnumeration.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedEnumeration.cpp index c7b31ce..cabd34e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedEnumeration.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedEnumeration.cpp @@ -80,7 +80,7 @@ JSSVGAnimatedEnumeration::JSSVGAnimatedEnumeration(PassRefPtr<Structure> structu JSSVGAnimatedEnumeration::~JSSVGAnimatedEnumeration() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedEnumeration::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedInteger.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedInteger.cpp index e49b71a..d19f136 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedInteger.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedInteger.cpp @@ -80,7 +80,7 @@ JSSVGAnimatedInteger::JSSVGAnimatedInteger(PassRefPtr<Structure> structure, JSDO JSSVGAnimatedInteger::~JSSVGAnimatedInteger() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedInteger::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLength.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLength.cpp index 7a5358d..851b70e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLength.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLength.cpp @@ -80,7 +80,7 @@ JSSVGAnimatedLength::JSSVGAnimatedLength(PassRefPtr<Structure> structure, JSDOMG JSSVGAnimatedLength::~JSSVGAnimatedLength() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedLength::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLengthList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLengthList.cpp index e4d23bc..6d403e3 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLengthList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedLengthList.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedLengthList::JSSVGAnimatedLengthList(PassRefPtr<Structure> structure JSSVGAnimatedLengthList::~JSSVGAnimatedLengthList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedLengthList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumber.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumber.cpp index cf3c932..0ccd0c9 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumber.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumber.cpp @@ -80,7 +80,7 @@ JSSVGAnimatedNumber::JSSVGAnimatedNumber(PassRefPtr<Structure> structure, JSDOMG JSSVGAnimatedNumber::~JSSVGAnimatedNumber() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedNumber::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumberList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumberList.cpp index 39857a1..756dd95 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumberList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedNumberList.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedNumberList::JSSVGAnimatedNumberList(PassRefPtr<Structure> structure JSSVGAnimatedNumberList::~JSSVGAnimatedNumberList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedNumberList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedPreserveAspectRatio.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedPreserveAspectRatio.cpp index 7196a26..c21644e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedPreserveAspectRatio.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedPreserveAspectRatio.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedPreserveAspectRatio::JSSVGAnimatedPreserveAspectRatio(PassRefPtr<St JSSVGAnimatedPreserveAspectRatio::~JSSVGAnimatedPreserveAspectRatio() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedPreserveAspectRatio::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedRect.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedRect.cpp index 483071b..f2d6c6c 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedRect.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedRect.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedRect::JSSVGAnimatedRect(PassRefPtr<Structure> structure, JSDOMGloba JSSVGAnimatedRect::~JSSVGAnimatedRect() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedRect::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedString.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedString.cpp index 3346799..ff997f8 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedString.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedString.cpp @@ -82,7 +82,7 @@ JSSVGAnimatedString::JSSVGAnimatedString(PassRefPtr<Structure> structure, JSDOMG JSSVGAnimatedString::~JSSVGAnimatedString() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedString::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedTransformList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedTransformList.cpp index ec0dcd1..2ac0fea 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedTransformList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGAnimatedTransformList.cpp @@ -81,7 +81,7 @@ JSSVGAnimatedTransformList::JSSVGAnimatedTransformList(PassRefPtr<Structure> str JSSVGAnimatedTransformList::~JSSVGAnimatedTransformList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGAnimatedTransformList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstance.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstance.cpp index e933025..3c611c3 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstance.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstance.cpp @@ -153,7 +153,7 @@ JSSVGElementInstance::JSSVGElementInstance(PassRefPtr<Structure> structure, JSDO JSSVGElementInstance::~JSSVGElementInstance() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGElementInstance::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstanceList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstanceList.cpp index 27f8939..66619a0 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstanceList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGElementInstanceList.cpp @@ -94,7 +94,7 @@ JSSVGElementInstanceList::JSSVGElementInstanceList(PassRefPtr<Structure> structu JSSVGElementInstanceList::~JSSVGElementInstanceList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGElementInstanceList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGException.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGException.cpp index b863c54..38f4d0d 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGException.cpp @@ -147,7 +147,7 @@ JSSVGException::JSSVGException(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSSVGException::~JSSVGException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGLength.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGLength.cpp index aa4d0bc..2182164 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGLength.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGLength.cpp @@ -166,7 +166,7 @@ JSSVGLength::JSSVGLength(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSSVGLength::~JSSVGLength() { JSSVGDynamicPODTypeWrapperCache<SVGLength, SVGAnimatedLength>::forgetWrapper(m_impl.get()); - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGLength::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGLengthList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGLengthList.cpp index 23b36a0..349aa59 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGLengthList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGLengthList.cpp @@ -100,7 +100,7 @@ JSSVGLengthList::JSSVGLengthList(PassRefPtr<Structure> structure, JSDOMGlobalObj JSSVGLengthList::~JSSVGLengthList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGLengthList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGMatrix.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGMatrix.cpp index 348aeb3..4f256da 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGMatrix.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGMatrix.cpp @@ -107,7 +107,7 @@ JSSVGMatrix::JSSVGMatrix(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSSVGMatrix::~JSSVGMatrix() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGMatrix::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGNumber.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGNumber.cpp index 0024f12..50137ef 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGNumber.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGNumber.cpp @@ -79,7 +79,7 @@ JSSVGNumber::JSSVGNumber(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSSVGNumber::~JSSVGNumber() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGNumber::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGNumberList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGNumberList.cpp index b5076f7..4e0629e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGNumberList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGNumberList.cpp @@ -99,7 +99,7 @@ JSSVGNumberList::JSSVGNumberList(PassRefPtr<Structure> structure, JSDOMGlobalObj JSSVGNumberList::~JSSVGNumberList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGNumberList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGPathSeg.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGPathSeg.cpp index 978e494..611adf1 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGPathSeg.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGPathSeg.cpp @@ -178,7 +178,7 @@ JSSVGPathSeg::JSSVGPathSeg(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSSVGPathSeg::~JSSVGPathSeg() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGPathSeg::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGPathSegList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGPathSegList.cpp index 1c0c405..7251554 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGPathSegList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGPathSegList.cpp @@ -99,7 +99,7 @@ JSSVGPathSegList::JSSVGPathSegList(PassRefPtr<Structure> structure, JSDOMGlobalO JSSVGPathSegList::~JSSVGPathSegList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGPathSegList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGPoint.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGPoint.cpp index 94faf9e..8719ece 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGPoint.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGPoint.cpp @@ -94,7 +94,7 @@ JSSVGPoint::JSSVGPoint(PassRefPtr<Structure> structure, JSDOMGlobalObject* globa JSSVGPoint::~JSSVGPoint() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGPoint::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGPointList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGPointList.cpp index 7953759..723b1ee 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGPointList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGPointList.cpp @@ -98,7 +98,7 @@ JSSVGPointList::JSSVGPointList(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSSVGPointList::~JSSVGPointList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGPointList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGPreserveAspectRatio.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGPreserveAspectRatio.cpp index 1ae7ea1..33b14ee 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGPreserveAspectRatio.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGPreserveAspectRatio.cpp @@ -164,7 +164,7 @@ JSSVGPreserveAspectRatio::JSSVGPreserveAspectRatio(PassRefPtr<Structure> structu JSSVGPreserveAspectRatio::~JSSVGPreserveAspectRatio() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGPreserveAspectRatio::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGRect.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGRect.cpp index fc762eb..321454a 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGRect.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGRect.cpp @@ -83,7 +83,7 @@ JSSVGRect::JSSVGRect(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSSVGRect::~JSSVGRect() { JSSVGDynamicPODTypeWrapperCache<FloatRect, SVGAnimatedRect>::forgetWrapper(m_impl.get()); - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGRect::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGRenderingIntent.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGRenderingIntent.cpp index 730a7a0..90c9caa 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGRenderingIntent.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGRenderingIntent.cpp @@ -145,7 +145,7 @@ JSSVGRenderingIntent::JSSVGRenderingIntent(PassRefPtr<Structure> structure, JSDO JSSVGRenderingIntent::~JSSVGRenderingIntent() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGRenderingIntent::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGStringList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGStringList.cpp index cddb511..4ad10bf 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGStringList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGStringList.cpp @@ -100,7 +100,7 @@ JSSVGStringList::JSSVGStringList(PassRefPtr<Structure> structure, JSDOMGlobalObj JSSVGStringList::~JSSVGStringList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGStringList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGTransform.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGTransform.cpp index 5478323..88d0c5f 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGTransform.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGTransform.cpp @@ -159,7 +159,7 @@ JSSVGTransform::JSSVGTransform(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSSVGTransform::~JSSVGTransform() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGTransform::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGTransformList.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGTransformList.cpp index 61a430c..1414d84 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGTransformList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGTransformList.cpp @@ -103,7 +103,7 @@ JSSVGTransformList::JSSVGTransformList(PassRefPtr<Structure> structure, JSDOMGlo JSSVGTransformList::~JSSVGTransformList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGTransformList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSVGUnitTypes.cpp b/src/3rdparty/webkit/WebCore/generated/JSSVGUnitTypes.cpp index eefc9a8..fd563b8 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSVGUnitTypes.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSSVGUnitTypes.cpp @@ -139,7 +139,7 @@ JSSVGUnitTypes::JSSVGUnitTypes(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSSVGUnitTypes::~JSSVGUnitTypes() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSSVGUnitTypes::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSScreen.cpp b/src/3rdparty/webkit/WebCore/generated/JSScreen.cpp index daa84c4..d39c2ef 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSScreen.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSScreen.cpp @@ -84,7 +84,7 @@ JSScreen::JSScreen(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObj JSScreen::~JSScreen() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSScreen::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSSharedWorkerContext.h b/src/3rdparty/webkit/WebCore/generated/JSSharedWorkerContext.h index 96ad865..092e13e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSSharedWorkerContext.h +++ b/src/3rdparty/webkit/WebCore/generated/JSSharedWorkerContext.h @@ -45,8 +45,6 @@ public: return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } - virtual void markChildren(JSC::MarkStack&); - SharedWorkerContext* impl() const { return static_cast<SharedWorkerContext*>(Base::impl()); @@ -61,10 +59,6 @@ public: void* operator new(size_t, JSC::JSGlobalData*); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) - { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); - } JSSharedWorkerContextPrototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { } }; diff --git a/src/3rdparty/webkit/WebCore/generated/JSStorage.cpp b/src/3rdparty/webkit/WebCore/generated/JSStorage.cpp index ed5b9f8..b3a6d47 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSStorage.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSStorage.cpp @@ -144,7 +144,7 @@ JSStorage::JSStorage(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalO JSStorage::~JSStorage() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSStorage::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSStyleSheet.cpp b/src/3rdparty/webkit/WebCore/generated/JSStyleSheet.cpp index 8b4c79b..6c2cef7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSStyleSheet.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSStyleSheet.cpp @@ -133,7 +133,7 @@ JSStyleSheet::JSStyleSheet(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSStyleSheet::~JSStyleSheet() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSStyleSheet::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSStyleSheetList.cpp b/src/3rdparty/webkit/WebCore/generated/JSStyleSheetList.cpp index 0f24ff3..b832c90 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSStyleSheetList.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSStyleSheetList.cpp @@ -138,7 +138,7 @@ JSStyleSheetList::JSStyleSheetList(PassRefPtr<Structure> structure, JSDOMGlobalO JSStyleSheetList::~JSStyleSheetList() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSStyleSheetList::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSTextMetrics.cpp b/src/3rdparty/webkit/WebCore/generated/JSTextMetrics.cpp index 9b28792..ea39518 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSTextMetrics.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSTextMetrics.cpp @@ -122,7 +122,7 @@ JSTextMetrics::JSTextMetrics(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSTextMetrics::~JSTextMetrics() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSTextMetrics::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSTimeRanges.cpp b/src/3rdparty/webkit/WebCore/generated/JSTimeRanges.cpp index 6dc04d2..25d7412 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSTimeRanges.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSTimeRanges.cpp @@ -93,7 +93,7 @@ JSTimeRanges::JSTimeRanges(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSTimeRanges::~JSTimeRanges() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSTimeRanges::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSTreeWalker.cpp b/src/3rdparty/webkit/WebCore/generated/JSTreeWalker.cpp index 290be89..b832247 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSTreeWalker.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSTreeWalker.cpp @@ -148,7 +148,7 @@ JSTreeWalker::JSTreeWalker(PassRefPtr<Structure> structure, JSDOMGlobalObject* g JSTreeWalker::~JSTreeWalker() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSTreeWalker::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSValidityState.cpp b/src/3rdparty/webkit/WebCore/generated/JSValidityState.cpp index 68fe415..f1df12e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSValidityState.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSValidityState.cpp @@ -84,7 +84,7 @@ JSValidityState::JSValidityState(PassRefPtr<Structure> structure, JSDOMGlobalObj JSValidityState::~JSValidityState() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSValidityState::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSVoidCallback.cpp b/src/3rdparty/webkit/WebCore/generated/JSVoidCallback.cpp index 186a349..570e851 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSVoidCallback.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSVoidCallback.cpp @@ -73,7 +73,7 @@ JSVoidCallback::JSVoidCallback(PassRefPtr<Structure> structure, JSDOMGlobalObjec JSVoidCallback::~JSVoidCallback() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSVoidCallback::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWebKitCSSMatrix.cpp b/src/3rdparty/webkit/WebCore/generated/JSWebKitCSSMatrix.cpp index 583c026..162b54c 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWebKitCSSMatrix.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWebKitCSSMatrix.cpp @@ -120,7 +120,7 @@ JSWebKitCSSMatrix::JSWebKitCSSMatrix(PassRefPtr<Structure> structure, JSDOMGloba JSWebKitCSSMatrix::~JSWebKitCSSMatrix() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSWebKitCSSMatrix::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWebKitPoint.cpp b/src/3rdparty/webkit/WebCore/generated/JSWebKitPoint.cpp index 3cba2f7..8d995e5 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWebKitPoint.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWebKitPoint.cpp @@ -78,7 +78,7 @@ JSWebKitPoint::JSWebKitPoint(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSWebKitPoint::~JSWebKitPoint() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSWebKitPoint::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWebSocket.cpp b/src/3rdparty/webkit/WebCore/generated/JSWebSocket.cpp index 9e69c8c..ca27dab 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWebSocket.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWebSocket.cpp @@ -29,6 +29,7 @@ #include "JSDOMGlobalObject.h" #include "JSEventListener.h" #include "KURL.h" +#include "RegisteredEventListener.h" #include "WebSocket.h" #include <runtime/Error.h> #include <runtime/JSNumberCell.h> @@ -115,7 +116,14 @@ JSWebSocket::JSWebSocket(PassRefPtr<Structure> structure, JSDOMGlobalObject* glo JSWebSocket::~JSWebSocket() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); +} + +void JSWebSocket::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + impl()->markEventListeners(markStack); } JSObject* JSWebSocket::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWorker.h b/src/3rdparty/webkit/WebCore/generated/JSWorker.h index f33b791..6b122a2 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWorker.h +++ b/src/3rdparty/webkit/WebCore/generated/JSWorker.h @@ -46,8 +46,6 @@ public: return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } - virtual void markChildren(JSC::MarkStack&); - // Custom functions JSC::JSValue postMessage(JSC::ExecState*, const JSC::ArgList&); @@ -70,7 +68,7 @@ public: virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::HasDefaultMark)); } JSWorkerPrototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { } }; diff --git a/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.cpp b/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.cpp index c5217d5..60fbc53 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.cpp @@ -35,6 +35,7 @@ #include "JSWorkerLocation.h" #include "JSWorkerNavigator.h" #include "JSXMLHttpRequest.h" +#include "RegisteredEventListener.h" #include "WorkerContext.h" #include "WorkerLocation.h" #include "WorkerNavigator.h" @@ -125,6 +126,12 @@ JSWorkerContext::JSWorkerContext(PassRefPtr<Structure> structure, PassRefPtr<Wor { } +JSWorkerContext::~JSWorkerContext() +{ + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); +} + bool JSWorkerContext::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { if (getOwnPropertySlotDelegate(exec, propertyName, slot)) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.h b/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.h index 1b4086e..4d112ad 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.h +++ b/src/3rdparty/webkit/WebCore/generated/JSWorkerContext.h @@ -33,6 +33,7 @@ class JSWorkerContext : public JSWorkerContextBase { typedef JSWorkerContextBase Base; public: JSWorkerContext(PassRefPtr<JSC::Structure>, PassRefPtr<WorkerContext>); + virtual ~JSWorkerContext(); virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); bool getOwnPropertySlotDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/generated/JSWorkerLocation.cpp b/src/3rdparty/webkit/WebCore/generated/JSWorkerLocation.cpp index 343fd91..b550a69 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWorkerLocation.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWorkerLocation.cpp @@ -153,7 +153,7 @@ JSWorkerLocation::JSWorkerLocation(PassRefPtr<Structure> structure, JSDOMGlobalO JSWorkerLocation::~JSWorkerLocation() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSWorkerLocation::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSWorkerNavigator.cpp b/src/3rdparty/webkit/WebCore/generated/JSWorkerNavigator.cpp index 618fd6e..ec04560 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSWorkerNavigator.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSWorkerNavigator.cpp @@ -93,7 +93,7 @@ JSWorkerNavigator::JSWorkerNavigator(PassRefPtr<Structure> structure, JSDOMGloba JSWorkerNavigator::~JSWorkerNavigator() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSWorkerNavigator::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequest.cpp b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequest.cpp index 0d5643e..a5cb5d0 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequest.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequest.cpp @@ -31,6 +31,7 @@ #include "JSEventListener.h" #include "JSXMLHttpRequestUpload.h" #include "KURL.h" +#include "RegisteredEventListener.h" #include "XMLHttpRequest.h" #include "XMLHttpRequestUpload.h" #include <runtime/Error.h> @@ -135,7 +136,8 @@ JSXMLHttpRequest::JSXMLHttpRequest(PassRefPtr<Structure> structure, JSDOMGlobalO JSXMLHttpRequest::~JSXMLHttpRequest() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXMLHttpRequest::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestException.cpp b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestException.cpp index e0bb84c..68c6dc2 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestException.cpp @@ -150,7 +150,7 @@ JSXMLHttpRequestException::JSXMLHttpRequestException(PassRefPtr<Structure> struc JSXMLHttpRequestException::~JSXMLHttpRequestException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXMLHttpRequestException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestUpload.cpp b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestUpload.cpp index d806fd24..de57982 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestUpload.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXMLHttpRequestUpload.cpp @@ -27,6 +27,7 @@ #include "JSDOMGlobalObject.h" #include "JSEvent.h" #include "JSEventListener.h" +#include "RegisteredEventListener.h" #include "XMLHttpRequestUpload.h" #include <runtime/Error.h> #include <wtf/GetPtr.h> @@ -153,7 +154,8 @@ JSXMLHttpRequestUpload::JSXMLHttpRequestUpload(PassRefPtr<Structure> structure, JSXMLHttpRequestUpload::~JSXMLHttpRequestUpload() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + impl()->invalidateEventListeners(); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXMLHttpRequestUpload::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXMLSerializer.cpp b/src/3rdparty/webkit/WebCore/generated/JSXMLSerializer.cpp index c4aca93..1e42f0e 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXMLSerializer.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXMLSerializer.cpp @@ -144,7 +144,7 @@ JSXMLSerializer::JSXMLSerializer(PassRefPtr<Structure> structure, JSDOMGlobalObj JSXMLSerializer::~JSXMLSerializer() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXMLSerializer::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXPathEvaluator.cpp b/src/3rdparty/webkit/WebCore/generated/JSXPathEvaluator.cpp index 33e8643..1e6a324 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXPathEvaluator.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXPathEvaluator.cpp @@ -155,7 +155,7 @@ JSXPathEvaluator::JSXPathEvaluator(PassRefPtr<Structure> structure, JSDOMGlobalO JSXPathEvaluator::~JSXPathEvaluator() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXPathEvaluator::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXPathException.cpp b/src/3rdparty/webkit/WebCore/generated/JSXPathException.cpp index d822318..1da8e93 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXPathException.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXPathException.cpp @@ -145,7 +145,7 @@ JSXPathException::JSXPathException(PassRefPtr<Structure> structure, JSDOMGlobalO JSXPathException::~JSXPathException() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXPathException::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXPathExpression.cpp b/src/3rdparty/webkit/WebCore/generated/JSXPathExpression.cpp index a5f4ce3..eaf7e26 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXPathExpression.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXPathExpression.cpp @@ -138,7 +138,7 @@ JSXPathExpression::JSXPathExpression(PassRefPtr<Structure> structure, JSDOMGloba JSXPathExpression::~JSXPathExpression() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXPathExpression::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXPathNSResolver.cpp b/src/3rdparty/webkit/WebCore/generated/JSXPathNSResolver.cpp index e9dbaa0..fc7a3d2 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXPathNSResolver.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXPathNSResolver.cpp @@ -79,7 +79,7 @@ JSXPathNSResolver::JSXPathNSResolver(PassRefPtr<Structure> structure, JSDOMGloba JSXPathNSResolver::~JSXPathNSResolver() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXPathNSResolver::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXPathResult.cpp b/src/3rdparty/webkit/WebCore/generated/JSXPathResult.cpp index 44f7bdd..9908dad 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXPathResult.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXPathResult.cpp @@ -168,7 +168,7 @@ JSXPathResult::JSXPathResult(PassRefPtr<Structure> structure, JSDOMGlobalObject* JSXPathResult::~JSXPathResult() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXPathResult::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/JSXSLTProcessor.cpp b/src/3rdparty/webkit/WebCore/generated/JSXSLTProcessor.cpp index 9e5ccd3..dec1fd4 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSXSLTProcessor.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSXSLTProcessor.cpp @@ -86,7 +86,7 @@ JSXSLTProcessor::JSXSLTProcessor(PassRefPtr<Structure> structure, JSDOMGlobalObj JSXSLTProcessor::~JSXSLTProcessor() { - forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get()); + forgetDOMObject(*Heap::heap(this)->globalData(), impl()); } JSObject* JSXSLTProcessor::createPrototype(ExecState* exec, JSGlobalObject* globalObject) diff --git a/src/3rdparty/webkit/WebCore/generated/WebKitVersion.h b/src/3rdparty/webkit/WebCore/generated/WebKitVersion.h index e7d6127..5dede20 100644 --- a/src/3rdparty/webkit/WebCore/generated/WebKitVersion.h +++ b/src/3rdparty/webkit/WebCore/generated/WebKitVersion.h @@ -31,6 +31,6 @@ #define WebKitVersion_h #define WEBKIT_MAJOR_VERSION 532 -#define WEBKIT_MINOR_VERSION 0 +#define WEBKIT_MINOR_VERSION 1 #endif //WebKitVersion_h diff --git a/src/3rdparty/webkit/WebCore/history/CachedFrame.cpp b/src/3rdparty/webkit/WebCore/history/CachedFrame.cpp index d542554..16c7087 100644 --- a/src/3rdparty/webkit/WebCore/history/CachedFrame.cpp +++ b/src/3rdparty/webkit/WebCore/history/CachedFrame.cpp @@ -29,11 +29,13 @@ #include "CachedFramePlatformData.h" #include "CString.h" #include "DocumentLoader.h" +#include "ExceptionCode.h" #include "EventNames.h" #include "Frame.h" #include "FrameLoaderClient.h" #include "FrameView.h" #include "Logging.h" +#include "PageTransitionEvent.h" #include <wtf/RefCountedLeakCounter.h> #if ENABLE(SVG) @@ -97,7 +99,7 @@ void CachedFrameBase::restore() for (unsigned i = 0; i < m_childFrames.size(); ++i) m_childFrames[i]->open(); - m_document->dispatchPageTransitionEvent(EventNames().pageshowEvent, true); + m_document->dispatchWindowEvent(PageTransitionEvent::create(EventNames().pageshowEvent, true), m_document); } CachedFrame::CachedFrame(Frame* frame) diff --git a/src/3rdparty/webkit/WebCore/html/HTMLAttributeNames.in b/src/3rdparty/webkit/WebCore/html/HTMLAttributeNames.in index f258bd7..63a5c21 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLAttributeNames.in +++ b/src/3rdparty/webkit/WebCore/html/HTMLAttributeNames.in @@ -167,6 +167,7 @@ onmouseup onmousewheel ononline onoffline +onorientationchange onpagehide onpageshow onpaste diff --git a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.cpp index 3813177..a356bf3 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.cpp @@ -143,6 +143,10 @@ void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr) document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr)); else if (attr->name() == onfocusAttr) document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr)); +#if ENABLE(ORIENTATION_EVENTS) + else if (attr->name() == onorientationchangeAttr) + document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr)); +#endif else if (attr->name() == onhashchangeAttr) document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr)); else if (attr->name() == onresizeAttr) @@ -322,124 +326,4 @@ void HTMLBodyElement::didMoveToNewOwnerDocument() HTMLElement::didMoveToNewOwnerDocument(); } -EventListener* HTMLBodyElement::onblur() const -{ - return document()->getWindowAttributeEventListener(eventNames().blurEvent); -} - -void HTMLBodyElement::setOnblur(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* HTMLBodyElement::onerror() const -{ - return document()->getWindowAttributeEventListener(eventNames().errorEvent); -} - -void HTMLBodyElement::setOnerror(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* HTMLBodyElement::onfocus() const -{ - return document()->getWindowAttributeEventListener(eventNames().focusEvent); -} - -void HTMLBodyElement::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* HTMLBodyElement::onload() const -{ - return document()->getWindowAttributeEventListener(eventNames().loadEvent); -} - -void HTMLBodyElement::setOnload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* HTMLBodyElement::onbeforeunload() const -{ - return document()->getWindowAttributeEventListener(eventNames().beforeunloadEvent); -} - -void HTMLBodyElement::setOnbeforeunload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, eventListener); -} - -EventListener* HTMLBodyElement::onhashchange() const -{ - return document()->getWindowAttributeEventListener(eventNames().hashchangeEvent); -} - -void HTMLBodyElement::setOnhashchange(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, eventListener); -} - -EventListener* HTMLBodyElement::onmessage() const -{ - return document()->getWindowAttributeEventListener(eventNames().messageEvent); -} - -void HTMLBodyElement::setOnmessage(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().messageEvent, eventListener); -} - -EventListener* HTMLBodyElement::onoffline() const -{ - return document()->getWindowAttributeEventListener(eventNames().offlineEvent); -} - -void HTMLBodyElement::setOnoffline(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().offlineEvent, eventListener); -} - -EventListener* HTMLBodyElement::ononline() const -{ - return document()->getWindowAttributeEventListener(eventNames().onlineEvent); -} - -void HTMLBodyElement::setOnonline(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().onlineEvent, eventListener); -} - -EventListener* HTMLBodyElement::onresize() const -{ - return document()->getWindowAttributeEventListener(eventNames().resizeEvent); -} - -void HTMLBodyElement::setOnresize(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().resizeEvent, eventListener); -} - -EventListener* HTMLBodyElement::onstorage() const -{ - return document()->getWindowAttributeEventListener(eventNames().storageEvent); -} - -void HTMLBodyElement::setOnstorage(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().storageEvent, eventListener); -} - -EventListener* HTMLBodyElement::onunload() const -{ - return document()->getWindowAttributeEventListener(eventNames().unloadEvent); -} - -void HTMLBodyElement::setOnunload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().unloadEvent, eventListener); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.h b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.h index d5efab3..e898c88 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.h @@ -25,6 +25,7 @@ #define HTMLBodyElement_h #include "HTMLElement.h" +#include "Document.h" namespace WebCore { @@ -44,31 +45,23 @@ public: String vLink() const; void setVLink(const String&); - virtual EventListener* onblur() const; - virtual void setOnblur(PassRefPtr<EventListener>); - virtual EventListener* onerror() const; - virtual void setOnerror(PassRefPtr<EventListener>); - virtual EventListener* onfocus() const; - virtual void setOnfocus(PassRefPtr<EventListener>); - virtual EventListener* onload() const; - virtual void setOnload(PassRefPtr<EventListener>); + // Declared virtual in Element + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load); - EventListener* onbeforeunload() const; - void setOnbeforeunload(PassRefPtr<EventListener>); - EventListener* onmessage() const; - void setOnmessage(PassRefPtr<EventListener>); - EventListener* onhashchange() const; - void setOnhashchange(PassRefPtr<EventListener>); - EventListener* onoffline() const; - void setOnoffline(PassRefPtr<EventListener>); - EventListener* ononline() const; - void setOnonline(PassRefPtr<EventListener>); - EventListener* onresize() const; - void setOnresize(PassRefPtr<EventListener>); - EventListener* onstorage() const; - void setOnstorage(PassRefPtr<EventListener>); - EventListener* onunload() const; - void setOnunload(PassRefPtr<EventListener>); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload); +#if ENABLE(ORIENTATION_EVENTS) + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange); +#endif private: virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.idl b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.idl index 7be6803..2e93e2e 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.idl +++ b/src/3rdparty/webkit/WebCore/html/HTMLBodyElement.idl @@ -44,6 +44,10 @@ module html { attribute [DontEnum] EventListener onstorage; attribute [DontEnum] EventListener onunload; +#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS + attribute [DontEnum] EventListener onorientationchange; +#endif + // Overrides of Element attributes (left in for completeness). // attribute [DontEnum] EventListener onblur; // attribute [DontEnum] EventListener onerror; diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFormControlElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLFormControlElement.cpp index 61e112c..bc74ecf 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFormControlElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLFormControlElement.cpp @@ -27,6 +27,7 @@ #include "ChromeClient.h" #include "Document.h" +#include "Event.h" #include "EventHandler.h" #include "EventNames.h" #include "Frame.h" @@ -186,7 +187,7 @@ void HTMLFormControlElement::setName(const AtomicString &value) void HTMLFormControlElement::dispatchFormControlChangeEvent() { - dispatchEvent(eventNames().changeEvent, true, false); + dispatchEvent(Event::create(eventNames().changeEvent, true, false)); } bool HTMLFormControlElement::disabled() const @@ -282,7 +283,7 @@ bool HTMLFormControlElement::willValidate() const bool HTMLFormControlElement::checkValidity() { if (willValidate() && !isValidFormControlElement()) { - dispatchEvent(EventNames().invalidEvent, false, true); + dispatchEvent(Event::create(EventNames().invalidEvent, false, true)); return false; } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp index 9f2d7c2..ace0f2f 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp @@ -150,14 +150,14 @@ void HTMLFormElement::removedFromDocument() HTMLElement::removedFromDocument(); } -void HTMLFormElement::handleLocalEvents(Event* event, bool useCapture) +void HTMLFormElement::handleLocalEvents(Event* event) { Node* targetNode = event->target()->toNode(); - if (!useCapture && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) { + if (event->eventPhase() != Event::CAPTURING_PHASE && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) { event->stopPropagation(); return; } - HTMLElement::handleLocalEvents(event, useCapture); + HTMLElement::handleLocalEvents(event); } unsigned HTMLFormElement::length() const @@ -296,7 +296,7 @@ bool HTMLFormElement::prepareSubmit(Event* event) m_insubmit = true; m_doingsubmit = false; - if (dispatchEvent(eventNames().submitEvent, true, true) && !m_doingsubmit) + if (dispatchEvent(Event::create(eventNames().submitEvent, true, true)) && !m_doingsubmit) m_doingsubmit = true; m_insubmit = false; @@ -416,7 +416,7 @@ void HTMLFormElement::reset() // ### DOM2 labels this event as not cancelable, however // common browsers( sick! ) allow it be cancelled. - if ( !dispatchEvent(eventNames().resetEvent, true, true) ) { + if (!dispatchEvent(Event::create(eventNames().resetEvent, true, true))) { m_inreset = false; return; } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.h b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.h index af81fcc..a2e9585 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.h @@ -54,7 +54,7 @@ public: virtual void insertedIntoDocument(); virtual void removedFromDocument(); - virtual void handleLocalEvents(Event*, bool useCapture); + virtual void handleLocalEvents(Event*); PassRefPtr<HTMLCollection> elements(); void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&); diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.cpp index 8dc3964..cbeba87 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.cpp @@ -135,6 +135,10 @@ void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr) document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr)); else if (attr->name() == onfocusAttr) document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr)); +#if ENABLE(ORIENTATION_EVENTS) + else if (attr->name() == onorientationchangeAttr) + document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr)); +#endif else if (attr->name() == onhashchangeAttr) document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr)); else if (attr->name() == onresizeAttr) @@ -230,124 +234,4 @@ void HTMLFrameSetElement::setRows(const String &value) setAttribute(rowsAttr, value); } -EventListener* HTMLFrameSetElement::onblur() const -{ - return document()->getWindowAttributeEventListener(eventNames().blurEvent); -} - -void HTMLFrameSetElement::setOnblur(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onerror() const -{ - return document()->getWindowAttributeEventListener(eventNames().errorEvent); -} - -void HTMLFrameSetElement::setOnerror(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onfocus() const -{ - return document()->getWindowAttributeEventListener(eventNames().focusEvent); -} - -void HTMLFrameSetElement::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onhashchange() const -{ - return document()->getWindowAttributeEventListener(eventNames().hashchangeEvent); -} - -void HTMLFrameSetElement::setOnhashchange(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onload() const -{ - return document()->getWindowAttributeEventListener(eventNames().loadEvent); -} - -void HTMLFrameSetElement::setOnload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onbeforeunload() const -{ - return document()->getWindowAttributeEventListener(eventNames().beforeunloadEvent); -} - -void HTMLFrameSetElement::setOnbeforeunload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onmessage() const -{ - return document()->getWindowAttributeEventListener(eventNames().messageEvent); -} - -void HTMLFrameSetElement::setOnmessage(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().messageEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onoffline() const -{ - return document()->getWindowAttributeEventListener(eventNames().offlineEvent); -} - -void HTMLFrameSetElement::setOnoffline(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().offlineEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::ononline() const -{ - return document()->getWindowAttributeEventListener(eventNames().onlineEvent); -} - -void HTMLFrameSetElement::setOnonline(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().onlineEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onresize() const -{ - return document()->getWindowAttributeEventListener(eventNames().resizeEvent); -} - -void HTMLFrameSetElement::setOnresize(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().resizeEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onstorage() const -{ - return document()->getWindowAttributeEventListener(eventNames().storageEvent); -} - -void HTMLFrameSetElement::setOnstorage(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().storageEvent, eventListener); -} - -EventListener* HTMLFrameSetElement::onunload() const -{ - return document()->getWindowAttributeEventListener(eventNames().unloadEvent); -} - -void HTMLFrameSetElement::setOnunload(PassRefPtr<EventListener> eventListener) -{ - document()->setWindowAttributeEventListener(eventNames().unloadEvent, eventListener); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.h b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.h index b51e702..2b2d7ea 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.h @@ -24,8 +24,9 @@ #ifndef HTMLFrameSetElement_h #define HTMLFrameSetElement_h -#include "HTMLElement.h" #include "Color.h" +#include "Document.h" +#include "HTMLElement.h" namespace WebCore { @@ -67,32 +68,23 @@ public: const Length* rowLengths() const { return m_rows; } const Length* colLengths() const { return m_cols; } - // Event handler attributes - virtual EventListener* onblur() const; - virtual void setOnblur(PassRefPtr<EventListener>); - virtual EventListener* onerror() const; - virtual void setOnerror(PassRefPtr<EventListener>); - virtual EventListener* onfocus() const; - virtual void setOnfocus(PassRefPtr<EventListener>); - virtual EventListener* onload() const; - virtual void setOnload(PassRefPtr<EventListener>); - - EventListener* onbeforeunload() const; - void setOnbeforeunload(PassRefPtr<EventListener>); - EventListener* onhashchange() const; - void setOnhashchange(PassRefPtr<EventListener>); - EventListener* onmessage() const; - void setOnmessage(PassRefPtr<EventListener>); - EventListener* onoffline() const; - void setOnoffline(PassRefPtr<EventListener>); - EventListener* ononline() const; - void setOnonline(PassRefPtr<EventListener>); - EventListener* onresize() const; - void setOnresize(PassRefPtr<EventListener>); - EventListener* onstorage() const; - void setOnstorage(PassRefPtr<EventListener>); - EventListener* onunload() const; - void setOnunload(PassRefPtr<EventListener>); + // Declared virtual in Element + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load); + + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage); + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload); +#if ENABLE(ORIENTATION_EVENTS) + DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange); +#endif private: Length* m_rows; diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.idl b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.idl index 0375c0a..b44a071 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.idl +++ b/src/3rdparty/webkit/WebCore/html/HTMLFrameSetElement.idl @@ -41,6 +41,10 @@ module html { attribute [DontEnum] EventListener onstorage; attribute [DontEnum] EventListener onunload; +#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS + attribute [DontEnum] EventListener onorientationchange; +#endif + // Overrides of Element attributes (left in for completeness). // attribute [DontEnum] EventListener onblur; // attribute [DontEnum] EventListener onerror; diff --git a/src/3rdparty/webkit/WebCore/html/HTMLImageLoader.cpp b/src/3rdparty/webkit/WebCore/html/HTMLImageLoader.cpp index 2b9f09c..c6f49aa 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLImageLoader.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLImageLoader.cpp @@ -25,6 +25,7 @@ #include "CSSHelper.h" #include "CachedImage.h" #include "Element.h" +#include "Event.h" #include "EventNames.h" #include "HTMLNames.h" #include "HTMLObjectElement.h" @@ -45,7 +46,7 @@ void HTMLImageLoader::dispatchLoadEvent() bool errorOccurred = image()->errorOccurred(); if (!errorOccurred && image()->httpStatusCodeErrorOccurred()) errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror. - element()->dispatchEvent(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false); + element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false)); } String HTMLImageLoader::sourceURI(const AtomicString& attr) const diff --git a/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp index 8b884cf..5ba780a 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp @@ -1742,7 +1742,7 @@ void HTMLInputElement::onSearch() ASSERT(isSearchField()); if (renderer()) toRenderTextControlSingleLine(renderer())->stopSearchEventTimer(); - dispatchEvent(eventNames().searchEvent, true, false); + dispatchEvent(Event::create(eventNames().searchEvent, true, false)); } VisibleSelection HTMLInputElement::selection() const diff --git a/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.cpp index 039d6f6..2409d37 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.cpp @@ -463,8 +463,8 @@ void HTMLMediaElement::loadInternal() bool totalKnown = m_player && m_player->totalBytesKnown(); unsigned loaded = m_player ? m_player->bytesLoaded() : 0; unsigned total = m_player ? m_player->totalBytes() : 0; - dispatchProgressEvent(eventNames().abortEvent, totalKnown, loaded, total); - dispatchProgressEvent(eventNames().loadendEvent, totalKnown, loaded, total); + dispatchEvent(ProgressEvent::create(eventNames().abortEvent, totalKnown, loaded, total)); + dispatchEvent(ProgressEvent::create(eventNames().loadendEvent, totalKnown, loaded, total)); } // 5 @@ -487,7 +487,7 @@ void HTMLMediaElement::loadInternal() m_playing = false; m_player->seek(0); } - dispatchEvent(eventNames().emptiedEvent, false, true); + dispatchEvent(Event::create(eventNames().emptiedEvent, false, true)); } selectMediaResource(); @@ -896,6 +896,13 @@ void HTMLMediaElement::returnToRealtime() setCurrentTime(maxTimeSeekable(), e); } +void HTMLMediaElement::addPlayedRange(float start, float end) +{ + if (!m_playedTimeRanges) + m_playedTimeRanges = TimeRanges::create(); + m_playedTimeRanges->add(start, end); +} + bool HTMLMediaElement::supportsSave() const { return m_player ? m_player->supportsSave() : false; @@ -931,7 +938,7 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec) // 5 if (m_playing) { if (m_lastSeekTime < now) - m_playedTimeRanges->add(m_lastSeekTime, now); + addPlayedRange(m_lastSeekTime, now); } m_lastSeekTime = time; @@ -1483,17 +1490,17 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const return m_player->buffered(); } -PassRefPtr<TimeRanges> HTMLMediaElement::played() const +PassRefPtr<TimeRanges> HTMLMediaElement::played() { - if (!m_playedTimeRanges) { - // We are not yet loaded - return TimeRanges::create(); - } if (m_playing) { float time = currentTime(); - if (m_lastSeekTime < time) - m_playedTimeRanges->add(m_lastSeekTime, time); + if (time > m_lastSeekTime) + addPlayedRange(m_lastSeekTime, time); } + + if (!m_playedTimeRanges) + m_playedTimeRanges = TimeRanges::create(); + return m_playedTimeRanges->copy(); } @@ -1589,8 +1596,8 @@ void HTMLMediaElement::updatePlayState() m_playbackProgressTimer.stop(); m_playing = false; float time = currentTime(); - if (m_lastSeekTime < time) - m_playedTimeRanges->add(m_lastSeekTime, time); + if (time > m_lastSeekTime) + addPlayedRange(m_lastSeekTime, time); } if (renderer()) @@ -1611,43 +1618,44 @@ void HTMLMediaElement::stopPeriodicTimers() void HTMLMediaElement::userCancelledLoad() { - if (m_networkState != NETWORK_EMPTY) { + if (m_networkState == NETWORK_EMPTY || m_networkState >= NETWORK_LOADED) + return; - // If the media data fetching process is aborted by the user: + // If the media data fetching process is aborted by the user: - // 1 - The user agent should cancel the fetching process. + // 1 - The user agent should cancel the fetching process. #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) - m_player.clear(); + m_player.clear(); #endif - stopPeriodicTimers(); + stopPeriodicTimers(); - // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORT. - m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); + // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORT. + m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); - // 3 - Queue a task to fire a progress event called abort at the media element, in the context - // of the fetching process started by this instance of this algorithm. - scheduleProgressEvent(eventNames().abortEvent); - - // 4 - Queue a task to fire a progress event called loadend at the media element, in the context - // of the fetching process started by this instance of this algorithm. - scheduleProgressEvent(eventNames().loadendEvent); - - // 5 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the - // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a - // simple event called emptied at the element. Otherwise, set set the element's networkState - // attribute to the NETWORK_IDLE value. - if (m_networkState >= NETWORK_LOADING) { - m_networkState = NETWORK_EMPTY; - m_readyState = HAVE_NOTHING; - scheduleEvent(eventNames().emptiedEvent); - } + // 3 - Queue a task to fire a progress event called abort at the media element, in the context + // of the fetching process started by this instance of this algorithm. + scheduleProgressEvent(eventNames().abortEvent); - // 6 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event. - m_delayingTheLoadEvent = false; + // 4 - Queue a task to fire a progress event called loadend at the media element, in the context + // of the fetching process started by this instance of this algorithm. + scheduleProgressEvent(eventNames().loadendEvent); - // 7 - Abort the overall resource selection algorithm. - m_currentSourceNode = 0; + // 5 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the + // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a + // simple event called emptied at the element. Otherwise, set set the element's networkState + // attribute to the NETWORK_IDLE value. + if (m_readyState == HAVE_NOTHING) { + m_networkState = NETWORK_EMPTY; + scheduleEvent(eventNames().emptiedEvent); } + else + m_networkState = NETWORK_IDLE; + + // 6 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event. + m_delayingTheLoadEvent = false; + + // 7 - Abort the overall resource selection algorithm. + m_currentSourceNode = 0; } void HTMLMediaElement::documentWillBecomeInactive() diff --git a/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.h b/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.h index 3aeb653..aa8d5f7 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLMediaElement.h @@ -120,7 +120,7 @@ public: void setPlaybackRate(float); bool webkitPreservesPitch() const; void setWebkitPreservesPitch(bool); - PassRefPtr<TimeRanges> played() const; + PassRefPtr<TimeRanges> played(); PassRefPtr<TimeRanges> seekable() const; bool ended() const; bool autoplay() const; @@ -193,6 +193,7 @@ private: void seek(float time, ExceptionCode&); void finishSeek(); void checkIfSeekNeeded(); + void addPlayedRange(float start, float end); void scheduleTimeupdateEvent(bool periodicEvent); void scheduleProgressEvent(const AtomicString& eventName); diff --git a/src/3rdparty/webkit/WebCore/html/HTMLScriptElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLScriptElement.cpp index 86cc3a2..ce7fee6 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLScriptElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLScriptElement.cpp @@ -24,6 +24,7 @@ #include "HTMLScriptElement.h" #include "Document.h" +#include "Event.h" #include "EventNames.h" #include "HTMLNames.h" #include "MappedAttribute.h" @@ -222,12 +223,12 @@ void HTMLScriptElement::dispatchLoadEvent() ASSERT(!m_data.haveFiredLoadEvent()); m_data.setHaveFiredLoadEvent(true); - dispatchEvent(eventNames().loadEvent, false, false); + dispatchEvent(Event::create(eventNames().loadEvent, false, false)); } void HTMLScriptElement::dispatchErrorEvent() { - dispatchEvent(eventNames().errorEvent, true, false); + dispatchEvent(Event::create(eventNames().errorEvent, true, false)); } } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLSourceElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLSourceElement.cpp index 2f09997..4b9401d 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLSourceElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLSourceElement.cpp @@ -28,6 +28,7 @@ #if ENABLE(VIDEO) #include "HTMLSourceElement.h" +#include "Event.h" #include "EventNames.h" #include "HTMLDocument.h" #include "HTMLMediaElement.h" @@ -105,7 +106,7 @@ void HTMLSourceElement::cancelPendingErrorEvent() void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*) { - dispatchEvent(eventNames().errorEvent, false, true); + dispatchEvent(Event::create(eventNames().errorEvent, false, true)); } } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.cpp index d3fc897..3cf4852 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "HTMLTextAreaElement.h" +#include "BeforeTextInsertedEvent.h" #include "ChromeClient.h" #include "CSSValueKeywords.h" #include "Document.h" @@ -35,12 +36,14 @@ #include "FormDataList.h" #include "Frame.h" #include "HTMLNames.h" +#include "InputElement.h" #include "MappedAttribute.h" #include "Page.h" #include "RenderStyle.h" #include "RenderTextControlMultiLine.h" #include "ScriptEventListener.h" #include "Text.h" +#include "TextIterator.h" #include "VisibleSelection.h" #include <wtf/StdLibExtras.h> @@ -270,10 +273,34 @@ void HTMLTextAreaElement::defaultEventHandler(Event* event) { if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent() || event->type() == eventNames().blurEvent)) toRenderTextControlMultiLine(renderer())->forwardEvent(event); + else if (renderer() && event->isBeforeTextInsertedEvent()) + handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event)); HTMLFormControlElementWithState::defaultEventHandler(event); } +void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const +{ + ASSERT(event); + ASSERT(renderer()); + bool ok; + unsigned maxLength = getAttribute(maxlengthAttr).string().toUInt(&ok); + if (!ok) + return; + + unsigned currentLength = toRenderTextControl(renderer())->text().numGraphemeClusters(); + unsigned selectionLength = plainText(document()->frame()->selection()->selection().toNormalizedRange().get()).numGraphemeClusters(); + ASSERT(currentLength >= selectionLength); + unsigned baseLength = currentLength - selectionLength; + unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; + event->setText(sanitizeUserInputValue(event->text(), appendableLength)); +} + +String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength) +{ + return proposedValue.left(proposedValue.numCharactersInGraphemeClusters(maxLength)); +} + void HTMLTextAreaElement::rendererWillBeDestroyed() { updateValue(); @@ -374,6 +401,16 @@ void HTMLTextAreaElement::setDefaultValue(const String& defaultValue) setValue(value); } +unsigned HTMLTextAreaElement::maxLength() const +{ + return getAttribute(maxlengthAttr).string().toUInt(); +} + +void HTMLTextAreaElement::setMaxLength(unsigned newValue) +{ + setAttribute(maxlengthAttr, String::number(newValue)); +} + void HTMLTextAreaElement::accessKeyAction(bool) { focus(); diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.h b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.h index 1f5cb91..fbf519d 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.h @@ -28,6 +28,7 @@ namespace WebCore { +class BeforeTextInsertedEvent; class VisibleSelection; class HTMLTextAreaElement : public HTMLFormControlElementWithState { @@ -78,6 +79,8 @@ public: String defaultValue() const; void setDefaultValue(const String&); int textLength() const { return value().length(); } + unsigned maxLength() const; + void setMaxLength(unsigned); void rendererWillBeDestroyed(); @@ -99,6 +102,8 @@ public: private: enum WrapMethod { NoWrap, SoftWrap, HardWrap }; + void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const; + static String sanitizeUserInputValue(const String&, unsigned maxLength); void updateValue() const; void updatePlaceholderVisibility(bool placeholderValueChanged); virtual void dispatchFocusEvent(); diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.idl b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.idl index 6d27f54..84583f5 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.idl +++ b/src/3rdparty/webkit/WebCore/html/HTMLTextAreaElement.idl @@ -34,6 +34,7 @@ module html { attribute long cols; attribute boolean disabled; attribute boolean autofocus; + attribute unsigned long maxLength; attribute [ConvertNullToNullString] DOMString name; attribute [ConvertNullToNullString, Reflect] DOMString placeholder; attribute boolean readOnly; diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp index 71faac0..fa68151 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp @@ -33,6 +33,7 @@ #include "CachedScript.h" #include "DocLoader.h" #include "DocumentFragment.h" +#include "Event.h" #include "EventNames.h" #include "Frame.h" #include "FrameLoader.h" @@ -2029,7 +2030,7 @@ void HTMLTokenizer::notifyFinished(CachedResource*) #endif if (errorOccurred) - n->dispatchEvent(eventNames().errorEvent, true, false); + n->dispatchEvent(Event::create(eventNames().errorEvent, true, false)); else { if (static_cast<HTMLScriptElement*>(n.get())->shouldExecuteAsJavaScript()) m_state = scriptExecution(sourceCode, m_state); @@ -2037,7 +2038,7 @@ void HTMLTokenizer::notifyFinished(CachedResource*) else m_doc->setShouldProcessNoscriptElement(true); #endif - n->dispatchEvent(eventNames().loadEvent, false, false); + n->dispatchEvent(Event::create(eventNames().loadEvent, false, false)); } // The state of m_pendingScripts.isEmpty() can change inside the scriptExecution() diff --git a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp index 1e3faa3..ed462fc 100644 --- a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -935,16 +935,13 @@ static inline FloatRect normalizeRect(const FloatRect& rect) void CanvasRenderingContext2D::checkOrigin(const KURL& url) { - RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url); - if (!m_canvas->document()->securityOrigin()->canAccess(origin.get())) + if (m_canvas->document()->securityOrigin()->taintsCanvas(url)) m_canvas->setOriginTainted(); } void CanvasRenderingContext2D::checkOrigin(const String& url) { - RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(url); - if (!m_canvas->document()->securityOrigin()->canAccess(origin.get())) - m_canvas->setOriginTainted(); + checkOrigin(KURL(KURL(), url)); } void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y) @@ -1208,8 +1205,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme if (!cachedImage || !image->cachedImage()->image()) return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true); - RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(cachedImage->url()); - bool originClean = m_canvas->document()->securityOrigin()->canAccess(origin.get()); + bool originClean = !m_canvas->document()->securityOrigin()->taintsCanvas(KURL(KURL(), cachedImage->url())); return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean); } diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.cpp index 25034fa..c140b13 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.cpp @@ -502,8 +502,26 @@ void InspectorBackend::selectDatabase(Database* database) #if ENABLE(DOM_STORAGE) void InspectorBackend::selectDOMStorage(Storage* storage) { - if (InspectorFrontend* frontend = inspectorFrontend()) - frontend->selectDOMStorage(storage); + if (m_inspectorController) + m_inspectorController->selectDOMStorage(storage); +} + +void InspectorBackend::getDOMStorageEntries(long callId, long storageId) +{ + if (m_inspectorController) + m_inspectorController->getDOMStorageEntries(callId, storageId); +} + +void InspectorBackend::setDOMStorageItem(long callId, long storageId, const String& key, const String& value) +{ + if (m_inspectorController) + m_inspectorController->setDOMStorageItem(callId, storageId, key, value); +} + +void InspectorBackend::removeDOMStorageItem(long callId, long storageId, const String& key) +{ + if (m_inspectorController) + m_inspectorController->removeDOMStorageItem(callId, storageId, key); } #endif diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.h b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.h index 22b46bf..038ae14 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.h @@ -151,6 +151,9 @@ public: #endif #if ENABLE(DOM_STORAGE) void selectDOMStorage(Storage* storage); + void getDOMStorageEntries(long callId, long storageId); + void setDOMStorageItem(long callId, long storageId, const String& key, const String& value); + void removeDOMStorageItem(long callId, long storageId, const String& key); #endif private: diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.idl b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.idl index 4540001..395e7fd 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.idl +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorBackend.idl @@ -121,6 +121,9 @@ module core { #endif #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE [Custom] void selectDOMStorage(in DOMObject storage); + void getDOMStorageEntries(in long callId, in long storageId); + void setDOMStorageItem(in long callId, in long storageId, in DOMString key, in DOMString value); + void removeDOMStorageItem(in long callId, in long storageId, in DOMString key); #endif }; } diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorController.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorController.cpp index 6498d84..69a7e60 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorController.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorController.cpp @@ -39,6 +39,7 @@ #include "CookieJar.h" #include "Document.h" #include "DocumentLoader.h" +#include "DOMWindow.h" #include "Element.h" #include "FloatConversion.h" #include "FloatQuad.h" @@ -643,6 +644,10 @@ void InspectorController::populateScriptObjects() if (!m_frontend) return; + // Initialize dom agent and reset injected script state first. + if (m_domAgent->setDocument(m_inspectedPage->mainFrame()->document())) + resetInjectedScript(); + ResourcesMap::iterator resourcesEnd = m_resources.end(); for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) it->second->createScriptObject(m_frontend.get()); @@ -662,8 +667,6 @@ void InspectorController::populateScriptObjects() (*it)->bind(m_frontend.get()); #endif - if (m_domAgent->setDocument(m_inspectedPage->mainFrame()->document())) - resetInjectedScript(); m_frontend->populateInterface(); } @@ -731,6 +734,9 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) m_currentUserInitiatedProfileNumber = 1; m_nextUserInitiatedProfileNumber = 1; #endif + // resetScriptObjects should be called before database and DOM storage + // resources are cleared so that it has a chance to unbind them. + resetScriptObjects(); #if ENABLE(DATABASE) m_databaseResources.clear(); #endif @@ -739,8 +745,6 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) #endif if (m_frontend) { - resetScriptObjects(); - if (!loader->frameLoader()->isLoadingFromCachedPage()) { ASSERT(m_mainResource && m_mainResource->isSameLoader(loader)); // We don't add the main resource until its load is committed. This is @@ -1108,6 +1112,86 @@ void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLoca if (m_frontend) resource->bind(m_frontend.get()); } + +void InspectorController::selectDOMStorage(Storage* storage) +{ + ASSERT(storage); + if (!m_frontend) + return; + + Frame* frame = storage->frame(); + bool isLocalStorage = (frame->domWindow()->localStorage() == storage); + int storageResourceId = 0; + DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end(); + for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) { + if ((*it)->isSameHostAndType(frame, isLocalStorage)) { + storageResourceId = (*it)->id(); + break; + } + } + if (storageResourceId) + m_frontend->selectDOMStorage(storageResourceId); +} + +void InspectorController::getDOMStorageEntries(int callId, int storageId) +{ + if (!m_frontend) + return; + + ScriptArray jsonArray = m_frontend->newScriptArray(); + InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId); + if (storageResource) { + storageResource->startReportingChangesToFrontend(); + Storage* domStorage = storageResource->domStorage(); + for (unsigned i = 0; i < domStorage->length(); ++i) { + String name(domStorage->key(i)); + String value(domStorage->getItem(name)); + ScriptArray entry = m_frontend->newScriptArray(); + entry.set(0, name); + entry.set(1, value); + jsonArray.set(i, entry); + } + } + m_frontend->didGetDOMStorageEntries(callId, jsonArray); +} + +void InspectorController::setDOMStorageItem(long callId, long storageId, const String& key, const String& value) +{ + if (!m_frontend) + return; + + bool success = false; + InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId); + if (storageResource) { + ExceptionCode exception = 0; + storageResource->domStorage()->setItem(key, value, exception); + success = (exception == 0); + } + m_frontend->didSetDOMStorageItem(callId, success); +} + +void InspectorController::removeDOMStorageItem(long callId, long storageId, const String& key) +{ + if (!m_frontend) + return; + + bool success = false; + InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId); + if (storageResource) { + storageResource->domStorage()->removeItem(key); + success = true; + } + m_frontend->didRemoveDOMStorageItem(callId, success); +} + +InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(int storageId) +{ + DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end(); + for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) + if ((*it)->id() == storageId) + return it->get(); + return 0; +} #endif void InspectorController::moveWindowBy(float x, float y) const @@ -1531,18 +1615,17 @@ InspectorController::SpecialPanels InspectorController::specialPanelForJSName(co ScriptValue InspectorController::wrapObject(const ScriptValue& quarantinedObject) { + ScriptFunctionCall function(m_scriptState, m_injectedScriptObj, "createProxyObject"); + function.appendArgument(quarantinedObject); if (quarantinedObject.isObject()) { long id = m_lastBoundObjectId++; String objectId = String::format("object#%ld", id); m_idToConsoleObject.set(objectId, quarantinedObject); - ScriptFunctionCall function(m_scriptState, m_injectedScriptObj, "createProxyObject"); - function.appendArgument(quarantinedObject); function.appendArgument(objectId); - ScriptValue wrapper = function.call(); - return wrapper; } - return quarantinedObject; + ScriptValue wrapper = function.call(); + return wrapper; } ScriptValue InspectorController::unwrapObject(const String& objectId) diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorController.h b/src/3rdparty/webkit/WebCore/inspector/InspectorController.h index f3e230e..20295aa 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorController.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorController.h @@ -74,6 +74,7 @@ class ResourceError; class ScriptCallStack; class ScriptString; class SharedBuffer; +class Storage; class StorageArea; class ConsoleMessage; @@ -232,6 +233,10 @@ public: #endif #if ENABLE(DOM_STORAGE) void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame); + void selectDOMStorage(Storage* storage); + void getDOMStorageEntries(int callId, int storageId); + void setDOMStorageItem(long callId, long storageId, const String& key, const String& value); + void removeDOMStorageItem(long callId, long storageId, const String& key); #endif const ResourcesMap& resources() const { return m_resources; } @@ -301,6 +306,9 @@ private: void toggleRecordButton(bool); void enableDebuggerFromFrontend(bool always); #endif +#if ENABLE(DOM_STORAGE) + InspectorDOMStorageResource* getDOMStorageResourceForId(int storageId); +#endif void focusNode(); diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.cpp index c7299d6..4a4902d 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.cpp @@ -123,7 +123,7 @@ void InspectorDOMAgent::stopListening(Document* doc) m_documents.remove(doc); } -void InspectorDOMAgent::handleEvent(Event* event, bool) +void InspectorDOMAgent::handleEvent(Event* event) { AtomicString type = event->type(); Node* node = event->target()->toNode(); diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.h b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.h index 3f4eaf5..bd539a5 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMAgent.h @@ -85,7 +85,7 @@ namespace WebCore { void startListening(Document* document); void stopListening(Document* document); - virtual void handleEvent(Event* event, bool isWindowEvent); + virtual void handleEvent(Event* event); typedef HashMap<RefPtr<Node>, long> NodeToIdMap; long bind(Node* node, NodeToIdMap* nodesMap); diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.cpp index 2f4aa53..99a2dba 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.cpp @@ -35,21 +35,28 @@ #include "InspectorDOMStorageResource.h" #include "Document.h" +#include "DOMWindow.h" +#include "EventNames.h" #include "Frame.h" #include "InspectorFrontend.h" #include "ScriptObject.h" -#include "ScriptObjectQuarantine.h" #include "Storage.h" +#include "StorageEvent.h" using namespace JSC; namespace WebCore { +int InspectorDOMStorageResource::s_nextUnusedId = 1; + InspectorDOMStorageResource::InspectorDOMStorageResource(Storage* domStorage, bool isLocalStorage, Frame* frame) - : m_domStorage(domStorage) + : EventListener(InspectorDOMStorageResourceType) + , m_domStorage(domStorage) , m_isLocalStorage(isLocalStorage) , m_frame(frame) - , m_scriptObjectCreated(false) + , m_frontend(0) + , m_id(s_nextUnusedId++) + , m_reportingChangesToFrontend(false) { } @@ -60,23 +67,49 @@ bool InspectorDOMStorageResource::isSameHostAndType(Frame* frame, bool isLocalSt void InspectorDOMStorageResource::bind(InspectorFrontend* frontend) { - if (m_scriptObjectCreated) - return; + ASSERT(!m_frontend); + m_frontend = frontend; ScriptObject jsonObject = frontend->newScriptObject(); - ScriptObject domStorage; - if (!getQuarantinedScriptObject(m_domStorage.get(), domStorage)) - return; - jsonObject.set("domStorage", domStorage); jsonObject.set("host", m_frame->document()->securityOrigin()->host()); jsonObject.set("isLocalStorage", m_isLocalStorage); - if (frontend->addDOMStorage(jsonObject)) - m_scriptObjectCreated = true; + jsonObject.set("id", m_id); + frontend->addDOMStorage(jsonObject); } void InspectorDOMStorageResource::unbind() { - m_scriptObjectCreated = false; + ASSERT(m_frontend); + if (m_reportingChangesToFrontend) { + m_frame->domWindow()->removeEventListener(eventNames().storageEvent, this, true); + m_reportingChangesToFrontend = false; + } + m_frontend = 0; +} + +void InspectorDOMStorageResource::startReportingChangesToFrontend() +{ + ASSERT(m_frontend); + if (!m_reportingChangesToFrontend) { + m_frame->domWindow()->addEventListener(eventNames().storageEvent, this, true); + m_reportingChangesToFrontend = true; + } +} + +void InspectorDOMStorageResource::handleEvent(Event* event) +{ + ASSERT(m_frontend); + ASSERT(eventNames().storageEvent == event->type()); + StorageEvent* storageEvent = static_cast<StorageEvent*>(event); + Storage* storage = storageEvent->storageArea(); + bool isLocalStorage = storageEvent->source()->localStorage() == storage; + if (isSameHostAndType(storage->frame(), isLocalStorage)) + m_frontend->updateDOMStorage(m_id); +} + +bool InspectorDOMStorageResource::operator==(const EventListener& listener) +{ + return (this == InspectorDOMStorageResource::cast(&listener)); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.h b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.h index 3e05897..6f29d9d 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorDOMStorageResource.h @@ -33,6 +33,7 @@ #if ENABLE(DOM_STORAGE) +#include "EventListener.h" #include "ScriptObject.h" #include "ScriptState.h" @@ -46,17 +47,27 @@ namespace WebCore { class Frame; class InspectorFrontend; - class InspectorDOMStorageResource : public RefCounted<InspectorDOMStorageResource> { + class InspectorDOMStorageResource : public EventListener { public: static PassRefPtr<InspectorDOMStorageResource> create(Storage* domStorage, bool isLocalStorage, Frame* frame) { return adoptRef(new InspectorDOMStorageResource(domStorage, isLocalStorage, frame)); } + static const InspectorDOMStorageResource* cast(const EventListener* listener) + { + return listener->type() == InspectorDOMStorageResourceType ? static_cast<const InspectorDOMStorageResource*>(listener) : 0; + } void bind(InspectorFrontend* frontend); void unbind(); + void startReportingChangesToFrontend(); + + virtual void handleEvent(Event*); + virtual bool operator==(const EventListener& listener); bool isSameHostAndType(Frame*, bool isLocalStorage) const; + long id() const { return m_id; } + Storage* domStorage() const { return m_domStorage.get(); } private: @@ -65,8 +76,11 @@ namespace WebCore { RefPtr<Storage> m_domStorage; bool m_isLocalStorage; RefPtr<Frame> m_frame; - bool m_scriptObjectCreated; + InspectorFrontend* m_frontend; + int m_id; + bool m_reportingChangesToFrontend; + static int s_nextUnusedId; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.cpp index c8a2f5c..3bdfa97 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.cpp @@ -83,8 +83,13 @@ void InspectorFrontend::addMessageToConsole(const ScriptObject& messageObj, cons } else if (!wrappedArguments.isEmpty()) { for (unsigned i = 0; i < wrappedArguments.size(); ++i) function->appendArgument(m_inspectorController->wrapObject(wrappedArguments[i])); - } else - function->appendArgument(message); + } else { + // FIXME: avoid manual wrapping here. + ScriptObject textWrapper = ScriptObject::createNew(m_scriptState); + textWrapper.set("type", "string"); + textWrapper.set("description", message); + function->appendArgument(textWrapper); + } function->call(); } @@ -399,13 +404,41 @@ void InspectorFrontend::selectDatabase(Database* database) #endif #if ENABLE(DOM_STORAGE) -void InspectorFrontend::selectDOMStorage(Storage* storage) +void InspectorFrontend::selectDOMStorage(int storageId) { OwnPtr<ScriptFunctionCall> function(newFunctionCall("selectDOMStorage")); - ScriptObject quarantinedObject; - if (!getQuarantinedScriptObject(storage, quarantinedObject)) - return; - function->appendArgument(quarantinedObject); + function->appendArgument(storageId); + function->call(); +} + +void InspectorFrontend::didGetDOMStorageEntries(int callId, const ScriptArray& entries) +{ + OwnPtr<ScriptFunctionCall> function(newFunctionCall("didGetDOMStorageEntries")); + function->appendArgument(callId); + function->appendArgument(entries); + function->call(); +} + +void InspectorFrontend::didSetDOMStorageItem(int callId, bool success) +{ + OwnPtr<ScriptFunctionCall> function(newFunctionCall("didSetDOMStorageItem")); + function->appendArgument(callId); + function->appendArgument(success); + function->call(); +} + +void InspectorFrontend::didRemoveDOMStorageItem(int callId, bool success) +{ + OwnPtr<ScriptFunctionCall> function(newFunctionCall("didRemoveDOMStorageItem")); + function->appendArgument(callId); + function->appendArgument(success); + function->call(); +} + +void InspectorFrontend::updateDOMStorage(int storageId) +{ + OwnPtr<ScriptFunctionCall> function(newFunctionCall("updateDOMStorage")); + function->appendArgument(storageId); function->call(); } #endif diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.h b/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.h index 42768e6..f9d3ba1 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorFrontend.h @@ -99,7 +99,11 @@ namespace WebCore { #if ENABLE(DOM_STORAGE) bool addDOMStorage(const ScriptObject& domStorageObj); - void selectDOMStorage(Storage* storage); + void selectDOMStorage(int storageId); + void didGetDOMStorageEntries(int callId, const ScriptArray& entries); + void didSetDOMStorageItem(int callId, bool success); + void didRemoveDOMStorageItem(int callId, bool success); + void updateDOMStorage(int storageId); #endif void setDocument(const ScriptObject& root); diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorResource.cpp b/src/3rdparty/webkit/WebCore/inspector/InspectorResource.cpp index 54d9f92..484a0bd 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorResource.cpp +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorResource.cpp @@ -264,32 +264,8 @@ String InspectorResource::sourceString() const if (!m_xmlHttpResponseText.isNull()) return String(m_xmlHttpResponseText); - RefPtr<SharedBuffer> buffer; String textEncodingName; - - if (m_requestURL == m_loader->requestURL()) { - buffer = m_loader->mainResourceData(); - textEncodingName = m_frame->document()->inputEncoding(); - } else { - CachedResource* cachedResource = m_frame->document()->docLoader()->cachedResource(requestURL()); - if (!cachedResource) - return String(); - - if (cachedResource->isPurgeable()) { - // If the resource is purgeable then make it unpurgeable to get - // get its data. This might fail, in which case we return an - // empty String. - // FIXME: should we do something else in the case of a purged - // resource that informs the user why there is no data in the - // inspector? - if (!cachedResource->makePurgeable(false)) - return String(); - } - - buffer = cachedResource->data(); - textEncodingName = cachedResource->encoding(); - } - + RefPtr<SharedBuffer> buffer = resourceData(&textEncodingName); if (!buffer) return String(); @@ -299,6 +275,31 @@ String InspectorResource::sourceString() const return encoding.decode(buffer->data(), buffer->size()); } +PassRefPtr<SharedBuffer> InspectorResource::resourceData(String* textEncodingName) const { + if (m_requestURL == m_loader->requestURL()) { + *textEncodingName = m_frame->document()->inputEncoding(); + return m_loader->mainResourceData(); + } + + CachedResource* cachedResource = m_frame->document()->docLoader()->cachedResource(requestURL()); + if (!cachedResource) + return 0; + + if (cachedResource->isPurgeable()) { + // If the resource is purgeable then make it unpurgeable to get + // get its data. This might fail, in which case we return an + // empty String. + // FIXME: should we do something else in the case of a purged + // resource that informs the user why there is no data in the + // inspector? + if (!cachedResource->makePurgeable(false)) + return 0; + } + + *textEncodingName = cachedResource->encoding(); + return cachedResource->data(); +} + void InspectorResource::startTiming() { m_startTime = currentTime(); diff --git a/src/3rdparty/webkit/WebCore/inspector/InspectorResource.h b/src/3rdparty/webkit/WebCore/inspector/InspectorResource.h index 4c85315..5e37e41 100644 --- a/src/3rdparty/webkit/WebCore/inspector/InspectorResource.h +++ b/src/3rdparty/webkit/WebCore/inspector/InspectorResource.h @@ -87,12 +87,20 @@ namespace WebCore { void setXMLHttpResponseText(const ScriptString& data); String sourceString() const; + PassRefPtr<SharedBuffer> resourceData(String* textEncodingName) const; + bool isSameLoader(DocumentLoader* loader) const { return loader == m_loader; } void markMainResource() { m_isMainResource = true; } long long identifier() const { return m_identifier; } String requestURL() const { return m_requestURL.string(); } Frame* frame() const { return m_frame.get(); } const String& mimeType() const { return m_mimeType; } + const HTTPHeaderMap& requestHeaderFields() const { return m_requestHeaderFields; } + const HTTPHeaderMap& responseHeaderFields() const { return m_responseHeaderFields; } + int responseStatusCode() const { return m_responseStatusCode; } + String requestMethod() const { return m_requestMethod; } + String requestFormData() const { return m_requestFormData; } + void startTiming(); void markResponseReceivedTime(); void endTiming(); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ConsoleView.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ConsoleView.js index 41b14ef..575b13a 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ConsoleView.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ConsoleView.js @@ -61,6 +61,14 @@ WebInspector.ConsoleView = function(drawer) // Will hold the list of filter elements this.filterBarElement = document.getElementById("console-filter"); + function createDividerElement() { + var dividerElement = document.createElement("div"); + + dividerElement.addStyleClass("divider"); + + this.filterBarElement.appendChild(dividerElement); + } + function createFilterElement(category) { var categoryElement = document.createElement("li"); categoryElement.category = category; @@ -77,6 +85,9 @@ WebInspector.ConsoleView = function(drawer) } this.allElement = createFilterElement.call(this, "All"); + + createDividerElement.call(this); + this.errorElement = createFilterElement.call(this, "Errors"); this.warningElement = createFilterElement.call(this, "Warnings"); this.logElement = createFilterElement.call(this, "Logs"); @@ -291,24 +302,10 @@ WebInspector.ConsoleView.prototype = { } } - function parsingCallback(result, isException) - { - if (!isException) - result = JSON.parse(result); - reportCompletions(result, isException); - } - - this.evalInInspectedWindow( - "(function() {" + - "var props = {};" + - "for (var prop in (" + expressionString + ")) props[prop] = true;" + - ((!dotNotation && !bracketNotation) ? - "for (var prop in window._inspectorCommandLineAPI)" + - "if (prop.charAt(0) !== '_') props[prop] = true;" - : "") + - "return JSON.stringify(props);" + - "})()", - parsingCallback); + var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation); + if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) + var callFrameId = WebInspector.panels.scripts.selectedCallFrameId(); + InjectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions); }, _reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) { @@ -611,7 +608,7 @@ WebInspector.ConsoleMessage.prototype = { this.formattedMessage = span; break; case WebInspector.ConsoleMessage.MessageType.Object: - this.formattedMessage = this._format(["%O", args[0]]); + this.formattedMessage = this._format([WebInspector.ObjectProxy.wrapPrimitiveValue("%O"), args[0]]); break; default: this.formattedMessage = this._format(args); @@ -644,7 +641,7 @@ WebInspector.ConsoleMessage.prototype = { return WebInspector.console._format(obj, true); } - if (typeof parameters[0] === "string") { + if (Object.proxyType(parameters[0]) === "string") { var formatters = {} for (var i in String.standardFormatters) formatters[i] = String.standardFormatters[i]; @@ -665,7 +662,7 @@ WebInspector.ConsoleMessage.prototype = { return a; } - var result = String.format(parameters[0], parameters.slice(1), formatters, formattedResult, append); + var result = String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append); formattedResult = result.formattedResult; parameters = result.unusedSubstitutions; if (parameters.length) @@ -673,8 +670,8 @@ WebInspector.ConsoleMessage.prototype = { } for (var i = 0; i < parameters.length; ++i) { - if (typeof parameters[i] === "string") - formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i])); + if (Object.proxyType(parameters[i]) === "string") + formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description)); else formattedResult.appendChild(formatForConsole(parameters[i])); @@ -916,7 +913,7 @@ WebInspector.ConsoleTextMessage.prototype.__proto__ = WebInspector.ConsoleMessag WebInspector.ConsoleCommandResult = function(result, exception, originatingCommand) { var level = (exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log); - var message = (exception ? String(result) : result); + var message = result; var line = (exception ? result.line : -1); var url = (exception ? result.sourceURL : null); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorage.js b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorage.js index 5207b69..03a10bf 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorage.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorage.js @@ -26,24 +26,22 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.DOMStorage = function(domStorage, domain, isLocalStorage) +WebInspector.DOMStorage = function(id, domain, isLocalStorage) { - this.domStorage = domStorage; - this.domain = domain; - this.isLocalStorage = isLocalStorage; + this._id = id; + this._domain = domain; + this._isLocalStorage = isLocalStorage; } WebInspector.DOMStorage.prototype = { - get domStorage() + get id() { - return this._domStorage; + return this._id; }, - set domStorage(x) + get domStorage() { - if (this._domStorage === x) - return; - this._domStorage = x; + return this._domStorage; }, get domain() @@ -51,22 +49,30 @@ WebInspector.DOMStorage.prototype = { return this._domain; }, - set domain(x) + get isLocalStorage() + { + return this._isLocalStorage; + }, + + getEntries: function(callback) { - if (this._domain === x) - return; - this._domain = x; + var callId = WebInspector.Callback.wrap(callback); + InspectorController.getDOMStorageEntries(callId, this._id); }, - get isLocalStorage() + setItem: function(key, value, callback) { - return this._isLocalStorage; + var callId = WebInspector.Callback.wrap(callback); + InspectorController.setDOMStorageItem(callId, this._id, key, value); }, - set isLocalStorage(x) + removeItem: function(key, callback) { - if (this._isLocalStorage === x) - return; - this._isLocalStorage = x; + var callId = WebInspector.Callback.wrap(callback); + InspectorController.removeDOMStorageItem(callId, this._id, key); } } + +WebInspector.didGetDOMStorageEntries = WebInspector.Callback.processCallback; +WebInspector.didSetDOMStorageItem = WebInspector.Callback.processCallback; +WebInspector.didRemoveDOMStorageItem = WebInspector.Callback.processCallback; diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageDataGrid.js b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageDataGrid.js index efdd090..45a9ba1 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageDataGrid.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageDataGrid.js @@ -23,10 +23,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.DOMStorageDataGrid = function(columns) +WebInspector.DOMStorageDataGrid = function(columns, domStorage, keys) { WebInspector.DataGrid.call(this, columns); this.dataTableBody.addEventListener("dblclick", this._ondblclick.bind(this), false); + this._domStorage = domStorage; + this._keys = keys; } WebInspector.DOMStorageDataGrid.prototype = { @@ -44,7 +46,6 @@ WebInspector.DOMStorageDataGrid.prototype = { this._editing = true; this._editingNode = node; this._editingNode.select(); - WebInspector.panels.storage._unregisterStorageEventListener(); var element = this._editingNode._element.children[column]; WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); @@ -69,7 +70,6 @@ WebInspector.DOMStorageDataGrid.prototype = { return this._startEditingColumnOfDataGridNode(this._editingNode, 0); this._editing = true; - WebInspector.panels.storage._unregisterStorageEventListener(); WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, @@ -118,22 +118,20 @@ WebInspector.DOMStorageDataGrid.prototype = { return; } - var domStorage = WebInspector.panels.storage.visibleView.domStorage.domStorage; - if (domStorage) { - if (columnIdentifier == 0) { - if (domStorage.getItem(newText) != null) { - element.textContent = this._editingNode.data[0]; - this._editingCancelled(element); - moveToNextIfNeeded.call(this, false); - return; - } - domStorage.removeItem(this._editingNode.data[0]); - domStorage.setItem(newText, this._editingNode.data[1]); - this._editingNode.data[0] = newText; - } else { - domStorage.setItem(this._editingNode.data[0], newText); - this._editingNode.data[1] = newText; + var domStorage = this._domStorage; + if (columnIdentifier === 0) { + if (this._keys.indexOf(newText) !== -1) { + element.textContent = this._editingNode.data[0]; + this._editingCancelled(element); + moveToNextIfNeeded.call(this, false); + return; } + domStorage.removeItem(this._editingNode.data[0]); + domStorage.setItem(newText, this._editingNode.data[1]); + this._editingNode.data[0] = newText; + } else { + domStorage.setItem(this._editingNode.data[0], newText); + this._editingNode.data[1] = newText; } if (this._editingNode.isCreationNode) @@ -147,18 +145,16 @@ WebInspector.DOMStorageDataGrid.prototype = { { delete this._editing; this._editingNode = null; - WebInspector.panels.storage._registerStorageEventListener(); }, deleteSelectedRow: function() { var node = this.selectedNode; - if (this.selectedNode.isCreationNode) + if (!node || node.isCreationNode) return; - var domStorage = WebInspector.panels.storage.visibleView.domStorage.domStorage; - if (node && domStorage) - domStorage.removeItem(node.data[0]); + if (this._domStorage) + this._domStorage.removeItem(node.data[0]); } } diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageItemsView.js b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageItemsView.js index 8617d60..a7da370 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageItemsView.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/DOMStorageItemsView.js @@ -61,39 +61,88 @@ WebInspector.DOMStorageItemsView.prototype = { update: function() { this.element.removeChildren(); - var hasDOMStorage = this.domStorage; - if (hasDOMStorage) - hasDOMStorage = this.domStorage.domStorage; - - if (hasDOMStorage) { - var dataGrid = WebInspector.panels.storage.dataGridForDOMStorage(this.domStorage.domStorage); - if (!dataGrid) - hasDOMStorage = 0; - else { - this._dataGrid = dataGrid; - this.element.appendChild(dataGrid.element); - this._dataGrid.updateWidths(); - this.deleteButton.visible = true; - } - } + var callback = this._showDOMStorageEntries.bind(this); + this.domStorage.getEntries(callback); + }, - if (!hasDOMStorage) { + _showDOMStorageEntries: function(entries) + { + if (entries.length > 0) { + this._dataGrid = this._dataGridForDOMStorageEntries(entries); + this.element.appendChild(this._dataGrid.element); + this._dataGrid.updateWidths(); + this.deleteButton.visible = true; + } else { var emptyMsgElement = document.createElement("div"); emptyMsgElement.className = "storage-table-empty"; if (this.domStorage) - emptyMsgElement.textContent = WebInspector.UIString("This storage is empty."); + emptyMsgElement.textContent = WebInspector.UIString("This storage is empty."); this.element.appendChild(emptyMsgElement); this._dataGrid = null; this.deleteButton.visible = false; } }, - + resize: function() { if (this._dataGrid) this._dataGrid.updateWidths(); }, + _dataGridForDOMStorageEntries: function(entries) + { + var columns = {}; + columns[0] = {}; + columns[1] = {}; + columns[0].title = WebInspector.UIString("Key"); + columns[0].width = columns[0].title.length; + columns[1].title = WebInspector.UIString("Value"); + columns[1].width = columns[1].title.length; + + var nodes = []; + + var keys = []; + var length = entries.length; + for (var i = 0; i < entries.length; i++) { + var data = {}; + + var key = entries[i][0]; + data[0] = key; + if (key.length > columns[0].width) + columns[0].width = key.length; + + var value = entries[i][1]; + data[1] = value; + if (value.length > columns[1].width) + columns[1].width = value.length; + var node = new WebInspector.DataGridNode(data, false); + node.selectable = true; + nodes.push(node); + keys.push(key); + } + + var totalColumnWidths = columns[0].width + columns[1].width; + var width = Math.round((columns[0].width * 100) / totalColumnWidths); + const minimumPrecent = 10; + if (width < minimumPrecent) + width = minimumPrecent; + if (width > 100 - minimumPrecent) + width = 100 - minimumPrecent; + columns[0].width = width; + columns[1].width = 100 - width; + columns[0].width += "%"; + columns[1].width += "%"; + + var dataGrid = new WebInspector.DOMStorageDataGrid(columns, this.domStorage, keys); + var length = nodes.length; + for (var i = 0; i < length; ++i) + dataGrid.appendChild(nodes[i]); + dataGrid.addCreationNode(false); + if (length > 0) + nodes[0].selected = true; + return dataGrid; + }, + _deleteButtonClicked: function(event) { if (this._dataGrid) { diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js index 08ba1c2..d8c4d89 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -31,7 +31,6 @@ WebInspector.ElementsTreeOutline = function() { this.element = document.createElement("ol"); this.element.addEventListener("mousedown", this._onmousedown.bind(this), false); - this.element.addEventListener("dblclick", this._ondblclick.bind(this), false); this.element.addEventListener("mousemove", this._onmousemove.bind(this), false); this.element.addEventListener("mouseout", this._onmouseout.bind(this), false); @@ -186,16 +185,6 @@ WebInspector.ElementsTreeOutline.prototype = { return element; }, - _ondblclick: function(event) - { - var element = this._treeElementFromEvent(event); - - if (!element || !element.ondblclick) - return; - - element.ondblclick(element, event); - }, - _onmousedown: function(event) { var element = this._treeElementFromEvent(event); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ImageView.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ImageView.js index 001ffdd..96e1a6e 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ImageView.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ImageView.js @@ -37,6 +37,7 @@ WebInspector.ImageView = function(resource) this.contentElement.appendChild(container); this.imagePreviewElement = document.createElement("img"); + this.imagePreviewElement.addStyleClass("resource-image-view"); this.imagePreviewElement.setAttribute("src", this.resource.url); container.appendChild(this.imagePreviewElement); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/Images/errorRedDot.png b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/errorRedDot.png Binary files differnew file mode 100644 index 0000000..6f0b164 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/errorRedDot.png diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/Images/successGreenDot.png b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/successGreenDot.png Binary files differnew file mode 100644 index 0000000..8b9319c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/successGreenDot.png diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/Images/warningOrangeDot.png b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/warningOrangeDot.png Binary files differnew file mode 100644 index 0000000..8c8b635 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/Images/warningOrangeDot.png diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScript.js b/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScript.js index 003e694..726c7cc 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScript.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScript.js @@ -421,7 +421,7 @@ InjectedScript.getPrototypes = function(nodeId) var result = []; for (var prototype = node; prototype; prototype = prototype.__proto__) { - var title = Object.describe(prototype); + var title = Object.describe(prototype, true); if (title.match(/Prototype$/)) { title = title.replace(/Prototype$/, ""); } @@ -498,43 +498,69 @@ InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression } } -InjectedScript.evaluate = function(expression) + +InjectedScript.getCompletions = function(expression, includeInspectorCommandLineAPI, callFrameId) { - return InjectedScript._evaluateOn(InjectedScript._window().eval, InjectedScript._window(), expression); + var props = {}; + try { + var expressionResult; + // Evaluate on call frame if call frame id is available. + if (typeof callFrameId === "number") { + var callFrame = InjectedScript._callFrameForId(callFrameId); + if (!callFrame) + return props; + expressionResult = InjectedScript._evaluateOn(callFrame.evaluate, callFrame, expression); + } else { + expressionResult = InjectedScript._evaluateOn(InjectedScript._window().eval, InjectedScript._window(), expression); + } + for (var prop in expressionResult) + props[prop] = true; + if (includeInspectorCommandLineAPI) + for (var prop in InjectedScript._window()._inspectorCommandLineAPI) + if (prop.charAt(0) !== '_') + props[prop] = true; + } catch(e) { + } + return props; } -InjectedScript._evaluateOn = function(evalFunction, object, expression) +InjectedScript.evaluate = function(expression) { - InjectedScript._ensureCommandLineAPIInstalled(); - // Surround the expression in with statements to inject our command line API so that - // the window object properties still take more precedent than our API functions. - expression = "with (window._inspectorCommandLineAPI) { with (window) { " + expression + " } }"; + return InjectedScript._evaluateAndWrap(InjectedScript._window().eval, InjectedScript._window(), expression); +} +InjectedScript._evaluateAndWrap = function(evalFunction, object, expression) +{ var result = {}; try { - var value = evalFunction.call(object, expression); - if (value === null) - return { value: null }; - if (Object.type(value) === "error") { - result.value = Object.describe(value); + result.value = InspectorController.wrapObject(InjectedScript._evaluateOn(evalFunction, object, expression)); + // Handle error that might have happened while describing result. + if (result.value.errorText) { + result.value = InspectorController.wrapObject(result.value.errorText); result.isException = true; - return result; - } - - var wrapper = InspectorController.wrapObject(value); - if (typeof wrapper === "object" && wrapper.exception) { - result.value = wrapper.exception; - result.isException = true; - } else { - result.value = wrapper; } } catch (e) { - result.value = e.toString(); + result.value = InspectorController.wrapObject(e.toString()); result.isException = true; } return result; } +InjectedScript._evaluateOn = function(evalFunction, object, expression) +{ + InjectedScript._ensureCommandLineAPIInstalled(); + // Surround the expression in with statements to inject our command line API so that + // the window object properties still take more precedent than our API functions. + expression = "with (window._inspectorCommandLineAPI) { with (window) { " + expression + " } }"; + var value = evalFunction.call(object, expression); + + // When evaluating on call frame error is not thrown, but returned as a value. + if (Object.type(value) === "error") + throw value.toString(); + + return value; +} + InjectedScript.addInspectedNode = function(nodeId) { var node = InjectedScript._nodeForId(nodeId); @@ -809,7 +835,7 @@ InjectedScript.evaluateInCallFrame = function(callFrameId, code) var callFrame = InjectedScript._callFrameForId(callFrameId); if (!callFrame) return false; - return InjectedScript._evaluateOn(callFrame.evaluate, callFrame, code); + return InjectedScript._evaluateAndWrap(callFrame.evaluate, callFrame, code); } InjectedScript._callFrameForId = function(id) @@ -950,7 +976,7 @@ InjectedScript.createProxyObject = function(object, objectId, abbreviate) result.type = Object.type(object); var type = typeof object; - if (type === "object" || type === "function") { + if ((type === "object" && object !== null) || type === "function") { for (var subPropertyName in object) { result.hasChildren = true; break; @@ -959,7 +985,7 @@ InjectedScript.createProxyObject = function(object, objectId, abbreviate) try { result.description = Object.describe(object, abbreviate); } catch (e) { - result.exception = e.toString(); + result.errorText = e.toString(); } return result; } @@ -982,11 +1008,11 @@ InjectedScript.CallFrameProxy.prototype = { var scopeChainProxy = []; for (var i = 0; i < scopeChain.length; ++i) { var scopeObject = scopeChain[i]; - var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: i }); + var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: i }, true); if (Object.prototype.toString.call(scopeObject) === "[object JSActivation]") { if (!foundLocalScope) - scopeObjectProxy.thisObject = InjectedScript.createProxyObject(callFrame.thisObject, { callFrame: this.id, thisObject: true }); + scopeObjectProxy.thisObject = InjectedScript.createProxyObject(callFrame.thisObject, { callFrame: this.id, thisObject: true }, true); else scopeObjectProxy.isClosure = true; foundLocalScope = true; @@ -1060,6 +1086,8 @@ Object.describe = function(obj, abbreviated) case "array": return "[" + obj.toString() + "]"; case "string": + if (!abbreviated) + return obj; if (obj.length > 100) return "\"" + obj.substring(0, 100) + "\u2026\""; return "\"" + obj + "\""; @@ -1072,6 +1100,10 @@ Object.describe = function(obj, abbreviated) return objectText; case "regexp": return String(obj).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1); + case "boolean": + case "number": + case "null": + return obj; default: return String(obj); } diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScriptAccess.js b/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScriptAccess.js index a5be2d8..da85d03 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScriptAccess.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/InjectedScriptAccess.js @@ -63,6 +63,7 @@ InjectedScriptAccess._installHandler("setStyleProperty"); InjectedScriptAccess._installHandler("getPrototypes"); InjectedScriptAccess._installHandler("getProperties"); InjectedScriptAccess._installHandler("setPropertyValue"); +InjectedScriptAccess._installHandler("getCompletions"); InjectedScriptAccess._installHandler("evaluate"); InjectedScriptAccess._installHandler("addInspectedNode"); InjectedScriptAccess._installHandler("pushNodeToFrontend"); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ObjectProxy.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ObjectProxy.js index 03d16ab..bb4afa5 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ObjectProxy.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ObjectProxy.js @@ -37,6 +37,14 @@ WebInspector.ObjectProxy = function(objectId, path, protoDepth, description, has this.hasChildren = hasChildren; } +WebInspector.ObjectProxy.wrapPrimitiveValue = function(value) +{ + var proxy = new WebInspector.ObjectProxy(); + proxy.type = typeof value; + proxy.description = value; + return proxy; +} + WebInspector.ObjectPropertyProxy = function(name, value) { this.name = name; diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/Resource.js b/src/3rdparty/webkit/WebCore/inspector/front-end/Resource.js index 4dac093..56696e3 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/Resource.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/Resource.js @@ -45,6 +45,64 @@ WebInspector.Resource = function(requestHeaders, url, domain, path, lastPathComp this.category = WebInspector.resourceCategories.other; } + +WebInspector.Resource.StatusText = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing (WebDav)", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status (WebDav)", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request-URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 422: "Unprocessable Entity (WebDav)", + 423: "Locked (WebDav)", + 424: "Failed Dependency (WebDav)", + 425: "Unordered Collection", + 426: "Upgrade Required", + 449: "Retry With", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage (WebDav)", + 509: "Bandwidth Limit Exceeded", + 510: "Not Extended" +}; + // Keep these in sync with WebCore::InspectorResource::Type WebInspector.Resource.Type = { Document: 0, @@ -620,3 +678,8 @@ WebInspector.Resource.CompareBySize = function(a, b) return 1; return 0; } + +WebInspector.Resource.StatusTextForCode = function(code) +{ + return code ? code + " " + WebInspector.Resource.StatusText[code] : ""; +} diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ResourceView.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ResourceView.js index d745920..d915055 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ResourceView.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ResourceView.js @@ -54,6 +54,11 @@ WebInspector.ResourceView = function(resource) this.urlTreeElement.selectable = false; this.headersTreeOutline.appendChild(this.urlTreeElement); + this.httpInformationTreeElement = new TreeElement("", null, true); + this.httpInformationTreeElement.expanded = false; + this.httpInformationTreeElement.selectable = false; + this.headersTreeOutline.appendChild(this.httpInformationTreeElement); + this.requestHeadersTreeElement = new TreeElement("", null, true); this.requestHeadersTreeElement.expanded = false; this.requestHeadersTreeElement.selectable = false; @@ -90,10 +95,12 @@ WebInspector.ResourceView = function(resource) resource.addEventListener("url changed", this._refreshURL, this); resource.addEventListener("requestHeaders changed", this._refreshRequestHeaders, this); resource.addEventListener("responseHeaders changed", this._refreshResponseHeaders, this); + resource.addEventListener("finished", this._refreshHTTPInformation, this); this._refreshURL(); this._refreshRequestHeaders(); this._refreshResponseHeaders(); + this._refreshHTTPInformation(); } WebInspector.ResourceView.prototype = { @@ -127,7 +134,21 @@ WebInspector.ResourceView.prototype = { _refreshURL: function() { var url = this.resource.url; - this.urlTreeElement.title = this.resource.requestMethod + " " + url.escapeHTML(); + var statusCodeImage = ""; + if (this.resource.statusCode) { + var statusImageSource = ""; + + if (this.resource.statusCode < 300) + statusImageSource = "Images/successGreenDot.png"; + else if (this.resource.statusCode < 400) + statusImageSource = "Images/warningOrangeDot.png"; + else + statusImageSource = "Images/errorRedDot.png"; + + statusCodeImage = "<img class=\"resource-status-image\" src=\"" + statusImageSource + "\" title=\"" + WebInspector.Resource.StatusTextForCode(this.resource.statusCode) + "\">"; + } + + this.urlTreeElement.title = statusCodeImage + "<span class=\"resource-url\">" + url.escapeHTML() + "</span>"; this._refreshQueryString(); }, @@ -240,6 +261,33 @@ WebInspector.ResourceView.prototype = { this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, this.responseHeadersTreeElement); }, + _refreshHTTPInformation: function() + { + const listElements = 2; + + var headerElement = this.httpInformationTreeElement; + headerElement.removeChildren(); + headerElement.hidden = !this.resource.statusCode; + + if (this.resource.statusCode) { + headerElement.title = WebInspector.UIString("HTTP Information") + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", listElements) + "</span>"; + + var title = "<div class=\"header-name\">" + WebInspector.UIString("Request Method") + ":</div>"; + title += "<div class=\"header-value\">" + this.resource.requestMethod + "</div>" + + var headerTreeElement = new TreeElement(title, null, false); + headerTreeElement.selectable = false; + headerElement.appendChild(headerTreeElement); + + title = "<div class=\"header-name\">" + WebInspector.UIString("Status Code") + ":</div>"; + title += "<div class=\"header-value\">" + WebInspector.Resource.StatusTextForCode(this.resource.statusCode) + "</div>" + + headerTreeElement = new TreeElement(title, null, false); + headerTreeElement.selectable = false; + headerElement.appendChild(headerTreeElement); + } + }, + _refreshHeaders: function(title, headers, headersTreeElement) { headersTreeElement.removeChildren(); diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/ScriptsPanel.js b/src/3rdparty/webkit/WebCore/inspector/front-end/ScriptsPanel.js index 04f27bb..ae918d1 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/ScriptsPanel.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/ScriptsPanel.js @@ -351,6 +351,14 @@ WebInspector.ScriptsPanel.prototype = { sourceFrame.removeBreakpoint(breakpoint); }, + selectedCallFrameId: function() + { + var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame; + if (!selectedCallFrame) + return null; + return selectedCallFrame.id; + }, + evaluateInSelectedCallFrame: function(code, updateInterface, callback) { var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame; diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/StoragePanel.js b/src/3rdparty/webkit/WebCore/inspector/front-end/StoragePanel.js index aed0d06..01c657d 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/StoragePanel.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/StoragePanel.js @@ -93,7 +93,6 @@ WebInspector.StoragePanel.prototype = { { WebInspector.Panel.prototype.show.call(this); this._updateSidebarWidth(); - this._registerStorageEventListener(); }, reset: function() @@ -110,8 +109,6 @@ WebInspector.StoragePanel.prototype = { this._databases = []; - this._unregisterStorageEventListener(); - if (this._domStorage) { var domStorageLength = this._domStorage.length; for (var i = 0; i < domStorageLength; ++i) { @@ -174,16 +171,12 @@ WebInspector.StoragePanel.prototype = { } }, - selectDOMStorage: function(s) + selectDOMStorage: function(storageId) { - var isLocalStorage = (s === InspectorController.inspectedWindow().localStorage); - for (var i = 0, len = this._domStorage.length; i < len; ++i) { - var storage = this._domStorage[i]; - if ( isLocalStorage === storage.isLocalStorage ) { - this.showDOMStorage(storage); - storage._domStorageTreeElement.select(); - return; - } + var domStorage = this._domStorageForId(storageId); + if (domStorage) { + this.showDOMStorage(domStorage); + domStorage._domStorageTreeElement.select(); } }, @@ -383,61 +376,6 @@ WebInspector.StoragePanel.prototype = { return dataGrid; }, - dataGridForDOMStorage: function(domStorage) - { - if (!domStorage.length) - return null; - - var columns = {}; - columns[0] = {}; - columns[1] = {}; - columns[0].title = WebInspector.UIString("Key"); - columns[0].width = columns[0].title.length; - columns[1].title = WebInspector.UIString("Value"); - columns[1].width = columns[1].title.length; - - var nodes = []; - - var length = domStorage.length; - for (var index = 0; index < domStorage.length; index++) { - var data = {}; - - var key = String(domStorage.key(index)); - data[0] = key; - if (key.length > columns[0].width) - columns[0].width = key.length; - - var value = String(domStorage.getItem(key)); - data[1] = value; - if (value.length > columns[1].width) - columns[1].width = value.length; - var node = new WebInspector.DataGridNode(data, false); - node.selectable = true; - nodes.push(node); - } - - var totalColumnWidths = columns[0].width + columns[1].width; - var width = Math.round((columns[0].width * 100) / totalColumnWidths); - const minimumPrecent = 10; - if (width < minimumPrecent) - width = minimumPrecent; - if (width > 100 - minimumPrecent) - width = 100 - minimumPrecent; - columns[0].width = width; - columns[1].width = 100 - width; - columns[0].width += "%"; - columns[1].width += "%"; - - var dataGrid = new WebInspector.DOMStorageDataGrid(columns); - var length = nodes.length; - for (var i = 0; i < length; ++i) - dataGrid.appendChild(nodes[i]); - dataGrid.addCreationNode(false); - if (length > 0) - nodes[0].selected = true; - return dataGrid; - }, - resize: function() { var visibleView = this.visibleView; @@ -445,44 +383,28 @@ WebInspector.StoragePanel.prototype = { visibleView.resize(); }, - _registerStorageEventListener: function() + updateDOMStorage: function(storageId) { - var inspectedWindow = InspectorController.inspectedWindow(); - if (!inspectedWindow || !inspectedWindow.document) - return; - - this._storageEventListener = InspectorController.wrapCallback(this._storageEvent.bind(this)); - inspectedWindow.addEventListener("storage", this._storageEventListener, true); - }, - - _unregisterStorageEventListener: function() - { - if (!this._storageEventListener) - return; - - var inspectedWindow = InspectorController.inspectedWindow(); - if (!inspectedWindow || !inspectedWindow.document) + var domStorage = this._domStorageForId(storageId); + if (!domStorage) return; - inspectedWindow.removeEventListener("storage", this._storageEventListener, true); - delete this._storageEventListener; + var view = domStorage._domStorageView; + if (this.visibleView && view === this.visibleView) + domStorage._domStorageView.update(); }, - _storageEvent: function(event) + _domStorageForId: function(storageId) { if (!this._domStorage) - return; - - var isLocalStorage = (event.storageArea === InspectorController.inspectedWindow().localStorage); + return null; var domStorageLength = this._domStorage.length; for (var i = 0; i < domStorageLength; ++i) { var domStorage = this._domStorage[i]; - if (isLocalStorage === domStorage.isLocalStorage) { - var view = domStorage._domStorageView; - if (this.visibleView && view === this.visibleView) - domStorage._domStorageView.update(); - } + if (domStorage.id == storageId) + return domStorage; } + return null; }, _startSidebarDragging: function(event) diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.css b/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.css index ea6f661..2ae4aac 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.css +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.css @@ -94,6 +94,10 @@ body.attached #toolbar { padding-left: 0; } +body.attached.platform-qt #toolbar { + cursor: auto; +} + body.attached.inactive #toolbar { border-top: 1px solid rgb(64%, 64%, 64%); } @@ -229,6 +233,10 @@ body.detached .toolbar-item.close { display: none; } +body.attached.platform-qt .toolbar-item.close { + display: none; +} + #main { position: absolute; z-index: 1; @@ -372,6 +380,10 @@ body.detached #dock-status-bar-item .glyph { -webkit-mask-image: url(Images/dockButtonGlyph.png); } +body.platform-qt #dock-status-bar-item { + display: none +} + #console-status-bar-item .glyph { -webkit-mask-image: url(Images/consoleButtonGlyph.png); } @@ -842,7 +854,7 @@ body.drawer-visible #drawer { -webkit-user-select: text; } -.resource-view.image img { +.resource-view.image img.resource-image-view { max-width: 100%; max-height: 1000px; background-image: url(Images/checker.png); @@ -851,6 +863,14 @@ body.drawer-visible #drawer { -webkit-user-drag: auto; } +.resource-url { + vertical-align: middle; +} + +.resource-status-image { + vertical-align: middle; +} + .resource-view.image .title { text-align: center; font-size: 13px; @@ -2327,6 +2347,15 @@ button.enable-toggle-status-bar-item.toggled-on .glyph { text-shadow: rgba(255, 255, 255, 0.5) 1px 1px 0; } +#console-filter div.divider { + margin-left: 5px; + margin-right: 5px; + /* Only want a border-left here because border on both sides + made the divider too thick */ + border-left: 1px solid gray; + display: inline; +} + #resources-filter li.selected, #resources-filter li:hover, #resources-filter li:active, #console-filter li.selected, #console-filter li:hover, #console-filter li:active { color: white; diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.js b/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.js index 902dd94..921bb7a 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/inspector.js @@ -784,7 +784,7 @@ WebInspector.toggleAttach = function() WebInspector.toolbarDragStart = function(event) { - if (!WebInspector.attached && InspectorController.platform() !== "mac-leopard") + if ((!WebInspector.attached && InspectorController.platform() !== "mac-leopard") || InspectorController.platform() == "qt") return; var target = event.target; @@ -1016,12 +1016,17 @@ WebInspector.addDatabase = function(payload) WebInspector.addDOMStorage = function(payload) { var domStorage = new WebInspector.DOMStorage( - payload.domStorage, + payload.id, payload.host, payload.isLocalStorage); this.panels.storage.addDOMStorage(domStorage); } +WebInspector.updateDOMStorage = function(storageId) +{ + this.panels.storage.updateDOMStorage(storageId); +} + WebInspector.resourceTrackingWasEnabled = function() { this.panels.resources.resourceTrackingWasEnabled(); @@ -1128,16 +1133,86 @@ WebInspector.addMessageToConsole = function(payload) WebInspector.log = function(message) { - var msg = new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.Other, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Debug, - -1, - null, - null, - 1, - message); - this.console.addMessage(msg); + // remember 'this' for setInterval() callback + var self = this; + + // return indication if we can actually log a message + function isLogAvailable() + { + return WebInspector.ConsoleMessage && WebInspector.ObjectProxy && self.console; + } + + // flush the queue of pending messages + function flushQueue() + { + var queued = WebInspector.log.queued; + if (!queued) + return; + + for (var i = 0; i < queued.length; ++i) + logMessage(queued[i]); + + delete WebInspector.log.queued; + } + + // flush the queue if it console is available + // - this function is run on an interval + function flushQueueIfAvailable() + { + if (!isLogAvailable()) + return; + + clearInterval(WebInspector.log.interval); + delete WebInspector.log.interval; + + flushQueue(); + } + + // actually log the message + function logMessage(message) + { + var repeatCount = 1; + if (message == WebInspector.log.lastMessage) + repeatCount = WebInspector.log.repeatCount + 1; + + WebInspector.log.lastMessage = message; + WebInspector.log.repeatCount = repeatCount; + + // ConsoleMessage expects a proxy object + message = new WebInspector.ObjectProxy(null, [], 0, message, false); + + // post the message + var msg = new WebInspector.ConsoleMessage( + WebInspector.ConsoleMessage.MessageSource.Other, + WebInspector.ConsoleMessage.MessageType.Log, + WebInspector.ConsoleMessage.MessageLevel.Debug, + -1, + null, + null, + repeatCount, + message); + + self.console.addMessage(msg); + } + + // if we can't log the message, queue it + if (!isLogAvailable()) { + if (!WebInspector.log.queued) + WebInspector.log.queued = []; + + WebInspector.log.queued.push(message); + + if (!WebInspector.log.interval) + WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000); + + return; + } + + // flush the pending queue if any + flushQueue(); + + // log the message + logMessage(message); } WebInspector.addProfile = function(profile) diff --git a/src/3rdparty/webkit/WebCore/inspector/front-end/utilities.js b/src/3rdparty/webkit/WebCore/inspector/front-end/utilities.js index e831abd..e83c7c0 100644 --- a/src/3rdparty/webkit/WebCore/inspector/front-end/utilities.js +++ b/src/3rdparty/webkit/WebCore/inspector/front-end/utilities.js @@ -814,12 +814,16 @@ String.tokenizeFormatString = function(format) String.standardFormatters = { d: function(substitution) { + if (typeof substitution == "object" && Object.proxyType(substitution) === "number") + substitution = substitution.description; substitution = parseInt(substitution); return !isNaN(substitution) ? substitution : 0; }, f: function(substitution, token) { + if (typeof substitution == "object" && Object.proxyType(substitution) === "number") + substitution = substitution.description; substitution = parseFloat(substitution); if (substitution && token.precision > -1) substitution = substitution.toFixed(token.precision); @@ -828,6 +832,8 @@ String.standardFormatters = { s: function(substitution) { + if (typeof substitution == "object" && Object.proxyType(substitution) !== "null") + substitution = substitution.description; return substitution; }, }; diff --git a/src/3rdparty/webkit/WebCore/loader/CachedResourceHandle.h b/src/3rdparty/webkit/WebCore/loader/CachedResourceHandle.h index 13c03c7..feb59b9 100644 --- a/src/3rdparty/webkit/WebCore/loader/CachedResourceHandle.h +++ b/src/3rdparty/webkit/WebCore/loader/CachedResourceHandle.h @@ -38,7 +38,8 @@ namespace WebCore { bool operator!() const { return !m_resource; } // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef CachedResource* CachedResourceHandleBase::*UnspecifiedBoolType; + // Parenthesis is needed for winscw compiler to resolve class qualifier in this case. + typedef CachedResource* (CachedResourceHandleBase::*UnspecifiedBoolType); operator UnspecifiedBoolType() const { return m_resource ? &CachedResourceHandleBase::m_resource : 0; } protected: @@ -59,7 +60,7 @@ namespace WebCore { template <class R> class CachedResourceHandle : public CachedResourceHandleBase { public: CachedResourceHandle() { } - CachedResourceHandle(R* res) : CachedResourceHandleBase(res) { } + CachedResourceHandle(R* res); CachedResourceHandle(const CachedResourceHandle<R>& o) : CachedResourceHandleBase(o) { } R* get() const { return reinterpret_cast<R*>(CachedResourceHandleBase::get()); } @@ -70,6 +71,16 @@ namespace WebCore { bool operator==(const CachedResourceHandleBase& o) const { return get() == o.get(); } bool operator!=(const CachedResourceHandleBase& o) const { return get() != o.get(); } }; + + // Don't inline for winscw compiler to prevent the compiler agressively resolving + // the base class of R* when CachedResourceHandler<T>(R*) is inlined. + template <class R> +#if !COMPILER(WINSCW) + inline +#endif + CachedResourceHandle<R>::CachedResourceHandle(R* res) : CachedResourceHandleBase(res) + { + } template <class R, class RR> bool operator==(const CachedResourceHandle<R>& h, const RR* res) { diff --git a/src/3rdparty/webkit/WebCore/loader/EmptyClients.h b/src/3rdparty/webkit/WebCore/loader/EmptyClients.h index 4172c06..41b6ebc 100644 --- a/src/3rdparty/webkit/WebCore/loader/EmptyClients.h +++ b/src/3rdparty/webkit/WebCore/loader/EmptyClients.h @@ -120,7 +120,7 @@ public: virtual void scroll(const IntSize&, const IntRect&, const IntRect&) { } virtual IntPoint screenToWindow(const IntPoint& p) const { return p; } virtual IntRect windowToScreen(const IntRect& r) const { return r; } - virtual PlatformWidget platformWindow() const { return 0; } + virtual PlatformPageClient platformPageClient() const { return 0; } virtual void contentsSizeChanged(Frame*, const IntSize&) const { } virtual void scrollbarsModeDidChange() const { } diff --git a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp index 4321be0..807edef 100644 --- a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp +++ b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp @@ -71,6 +71,7 @@ #include "Page.h" #include "PageCache.h" #include "PageGroup.h" +#include "PageTransitionEvent.h" #include "PlaceholderDocument.h" #include "PluginData.h" #include "PluginDocument.h" @@ -138,6 +139,7 @@ struct ScheduledRedirection { const bool wasUserGesture; const bool wasRefresh; const bool wasDuringLoad; + bool toldClient; ScheduledRedirection(double delay, const String& url, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh) : type(redirection) @@ -149,6 +151,7 @@ struct ScheduledRedirection { , wasUserGesture(wasUserGesture) , wasRefresh(refresh) , wasDuringLoad(false) + , toldClient(false) { ASSERT(!url.isEmpty()); } @@ -164,6 +167,7 @@ struct ScheduledRedirection { , wasUserGesture(wasUserGesture) , wasRefresh(refresh) , wasDuringLoad(duringLoad) + , toldClient(false) { ASSERT(!url.isEmpty()); } @@ -177,6 +181,7 @@ struct ScheduledRedirection { , wasUserGesture(false) , wasRefresh(false) , wasDuringLoad(false) + , toldClient(false) { } @@ -194,6 +199,7 @@ struct ScheduledRedirection { , wasUserGesture(false) , wasRefresh(false) , wasDuringLoad(duringLoad) + , toldClient(false) { ASSERT(!frameRequest.isEmpty()); ASSERT(this->formState); @@ -267,8 +273,9 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_encodingWasChosenByUser(false) , m_containsPlugIns(false) , m_redirectionTimer(this, &FrameLoader::redirectionTimerFired) - , m_checkCompletedTimer(this, &FrameLoader::checkCompletedTimerFired) - , m_checkLoadCompleteTimer(this, &FrameLoader::checkLoadCompleteTimerFired) + , m_checkTimer(this, &FrameLoader::checkTimerFired) + , m_shouldCallCheckCompleted(false) + , m_shouldCallCheckLoadComplete(false) , m_opener(0) , m_openedByDOM(false) , m_creatingInitialEmptyDocument(false) @@ -318,6 +325,11 @@ void FrameLoader::setDefersLoading(bool defers) m_provisionalDocumentLoader->setDefersLoading(defers); if (m_policyDocumentLoader) m_policyDocumentLoader->setDefersLoading(defers); + + if (!defers) { + startRedirectionTimer(); + startCheckCompleteTimer(); + } } Frame* FrameLoader::createWindow(FrameLoader* frameLoaderForFrameLookup, const FrameLoadRequest& request, const WindowFeatures& features, bool& created) @@ -581,9 +593,9 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic m_unloadEventBeingDispatched = true; if (m_frame->domWindow()) { if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) - m_frame->domWindow()->dispatchPageTransitionEvent(EventNames().pagehideEvent, m_frame->document()->inPageCache()); + m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document()); if (!m_frame->document()->inPageCache()) - m_frame->domWindow()->dispatchUnloadEvent(); + m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document()); } m_unloadEventBeingDispatched = false; if (m_frame->document()) @@ -597,7 +609,7 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic m_frame->document()->removeAllEventListeners(); } - m_isComplete = true; // to avoid calling completed() in finishedParsing() (David) + m_isComplete = true; // to avoid calling completed() in finishedParsing() m_isLoadingMainResource = false; m_didCallImplicitClose = true; // don't want that one either @@ -656,8 +668,6 @@ void FrameLoader::cancelRedirection(bool cancelWithLoadInProgress) m_cancellingWithLoadInProgress = cancelWithLoadInProgress; stopRedirectionTimer(); - - m_scheduledRedirection.clear(); } KURL FrameLoader::iconURL() @@ -743,8 +753,10 @@ bool FrameLoader::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool const int javascriptSchemeLength = sizeof("javascript:") - 1; - String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength)); - ScriptValue result = executeScript(script, userGesture); + String script = url.string().substring(javascriptSchemeLength); + ScriptValue result; + if (m_frame->script()->xssAuditor()->canEvaluateJavaScriptURL(script)) + result = executeScript(decodeURLEscapeSequences(script), userGesture); String scriptResult; if (!result.getString(scriptResult)) @@ -844,8 +856,9 @@ void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, boo m_redirectionTimer.stop(); m_scheduledRedirection.clear(); - m_checkCompletedTimer.stop(); - m_checkLoadCompleteTimer.stop(); + m_checkTimer.stop(); + m_shouldCallCheckCompleted = false; + m_shouldCallCheckLoadComplete = false; m_receivedData = false; m_isDisplayingInitialEmptyDocument = false; @@ -1238,15 +1251,34 @@ void FrameLoader::loadDone() checkCompleted(); } +bool FrameLoader::allChildrenAreComplete() const +{ + for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { + if (!child->loader()->m_isComplete) + return false; + } + return true; +} + +bool FrameLoader::allAncestorsAreComplete() const +{ + for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree()->parent()) { + if (!ancestor->loader()->m_isComplete) + return false; + } + return true; +} + void FrameLoader::checkCompleted() { + m_shouldCallCheckCompleted = false; + if (m_frame->view()) m_frame->view()->checkStopDelayingDeferredRepaints(); // Any frame that hasn't completed yet? - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - if (!child->loader()->m_isComplete) - return; + if (!allChildrenAreComplete()) + return; // Have we completed before? if (m_isComplete) @@ -1266,38 +1298,44 @@ void FrameLoader::checkCompleted() RefPtr<Frame> protect(m_frame); checkCallImplicitClose(); // if we didn't do it before - // Do not start a redirection timer for subframes here. - // That is deferred until the parent is completed. - if (m_scheduledRedirection && !m_frame->tree()->parent()) - startRedirectionTimer(); + startRedirectionTimer(); completed(); if (m_frame->page()) checkLoadComplete(); } -void FrameLoader::checkCompletedTimerFired(Timer<FrameLoader>*) +void FrameLoader::checkTimerFired(Timer<FrameLoader>*) { - checkCompleted(); + if (Page* page = m_frame->page()) { + if (page->defersLoading()) + return; + } + if (m_shouldCallCheckCompleted) + checkCompleted(); + if (m_shouldCallCheckLoadComplete) + checkLoadComplete(); } -void FrameLoader::scheduleCheckCompleted() +void FrameLoader::startCheckCompleteTimer() { - if (!m_checkCompletedTimer.isActive()) - m_checkCompletedTimer.startOneShot(0); + if (!(m_shouldCallCheckCompleted || m_shouldCallCheckLoadComplete)) + return; + if (m_checkTimer.isActive()) + return; + m_checkTimer.startOneShot(0); } -void FrameLoader::checkLoadCompleteTimerFired(Timer<FrameLoader>*) +void FrameLoader::scheduleCheckCompleted() { - if (!m_frame->page()) - return; - checkLoadComplete(); + m_shouldCallCheckCompleted = true; + startCheckCompleteTimer(); } void FrameLoader::scheduleCheckLoadComplete() { - if (!m_checkLoadCompleteTimer.isActive()) - m_checkLoadCompleteTimer.startOneShot(0); + m_shouldCallCheckLoadComplete = true; + startCheckCompleteTimer(); } void FrameLoader::checkCallImplicitClose() @@ -1305,9 +1343,8 @@ void FrameLoader::checkCallImplicitClose() if (m_didCallImplicitClose || m_frame->document()->parsing()) return; - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - if (!child->loader()->m_isComplete) // still got a frame running -> too early - return; + if (!allChildrenAreComplete()) + return; // still got a frame running -> too early m_didCallImplicitClose = true; m_wasUnloadEventEmitted = false; @@ -1427,12 +1464,6 @@ void FrameLoader::scheduleHistoryNavigation(int steps) if (!m_frame->page()) return; - // navigation will always be allowed in the 0 steps case, which is OK because that's supposed to force a reload. - if (!canGoBackOrForward(steps)) { - cancelRedirection(); - return; - } - scheduleRedirection(new ScheduledRedirection(steps)); } @@ -1470,6 +1501,9 @@ void FrameLoader::redirectionTimerFired(Timer<FrameLoader>*) { ASSERT(m_frame->page()); + if (m_frame->page()->defersLoading()) + return; + OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); switch (redirection->type) { @@ -1486,7 +1520,8 @@ void FrameLoader::redirectionTimerFired(Timer<FrameLoader>*) } // go(i!=0) from a frame navigates into the history of the frame only, // in both IE and NS (but not in Mozilla). We can't easily do that. - goBackOrForward(redirection->historySteps); + if (canGoBackOrForward(redirection->historySteps)) + goBackOrForward(redirection->historySteps); return; case ScheduledRedirection::formSubmission: // The submitForm function will find a target frame before using the redirection timer. @@ -1710,12 +1745,6 @@ bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String return widget != 0; } -void FrameLoader::parentCompleted() -{ - if (m_scheduledRedirection && !m_redirectionTimer.isActive()) - startRedirectionTimer(); -} - String FrameLoader::outgoingReferrer() const { return m_outgoingReferrer; @@ -1854,7 +1883,7 @@ bool FrameLoader::canCachePageContainingThisFrame() && !m_containsPlugIns && !m_URL.protocolIs("https") #ifndef PAGE_CACHE_ACCEPTS_UNLOAD_HANDLERS - && (!m_frame->domWindow() || !m_frame->domWindow()->hasEventListener(eventNames().unloadEvent)) + && (!m_frame->domWindow() || !m_frame->domWindow()->hasEventListeners(eventNames().unloadEvent)) #endif #if ENABLE(DATABASE) && !m_frame->document()->hasOpenDatabases() @@ -2001,7 +2030,7 @@ bool FrameLoader::logCanCacheFrameDecision(int indentLevel) if (m_URL.protocolIs("https")) { PCLOG(" -Frame is HTTPS"); cannotCache = true; } #ifndef PAGE_CACHE_ACCEPTS_UNLOAD_HANDLERS - if (m_frame->domWindow() && m_frame->domWindow()->hasEventListener(eventNames().unloadEvent)) + if (m_frame->domWindow() && m_frame->domWindow()->hasEventListeners(eventNames().unloadEvent)) { PCLOG(" -Frame has an unload event listener"); cannotCache = true; } #endif #if ENABLE(DATABASE) @@ -2068,7 +2097,7 @@ public: virtual void performTask(ScriptExecutionContext* context) { ASSERT_UNUSED(context, context->isDocument()); - m_document->dispatchWindowEvent(eventNames().hashchangeEvent, false, false); + m_document->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false)); } private: @@ -2110,7 +2139,7 @@ bool FrameLoader::isComplete() const return m_isComplete; } -void FrameLoader::scheduleRedirection(ScheduledRedirection* redirection) +void FrameLoader::scheduleRedirection(PassOwnPtr<ScheduledRedirection> redirection) { ASSERT(m_frame->page()); @@ -2124,24 +2153,33 @@ void FrameLoader::scheduleRedirection(ScheduledRedirection* redirection) } stopRedirectionTimer(); - m_scheduledRedirection.set(redirection); - if (!m_isComplete && redirection->type != ScheduledRedirection::redirection) + m_scheduledRedirection = redirection; + if (!m_isComplete && m_scheduledRedirection->type != ScheduledRedirection::redirection) completed(); - if (m_isComplete || redirection->type != ScheduledRedirection::redirection) - startRedirectionTimer(); + startRedirectionTimer(); } void FrameLoader::startRedirectionTimer() { + if (!m_scheduledRedirection) + return; + ASSERT(m_frame->page()); - ASSERT(m_scheduledRedirection); - m_redirectionTimer.stop(); + if (m_redirectionTimer.isActive()) + return; + + if (m_scheduledRedirection->type == ScheduledRedirection::redirection && !allAncestorsAreComplete()) + return; + m_redirectionTimer.startOneShot(m_scheduledRedirection->delay); switch (m_scheduledRedirection->type) { case ScheduledRedirection::locationChange: case ScheduledRedirection::redirection: + if (m_scheduledRedirection->toldClient) + return; + m_scheduledRedirection->toldClient = true; clientRedirected(KURL(ParsedURLString, m_scheduledRedirection->url), m_scheduledRedirection->delay, currentTime() + m_redirectionTimer.nextFireInterval(), @@ -2161,35 +2199,18 @@ void FrameLoader::startRedirectionTimer() void FrameLoader::stopRedirectionTimer() { - if (!m_redirectionTimer.isActive()) - return; - m_redirectionTimer.stop(); - if (m_scheduledRedirection) { - switch (m_scheduledRedirection->type) { - case ScheduledRedirection::locationChange: - case ScheduledRedirection::redirection: - clientRedirectCancelledOrFinished(m_cancellingWithLoadInProgress); - return; - case ScheduledRedirection::formSubmission: - // FIXME: It would make sense to report form submissions as client redirects too. - // But we didn't do that in the past when form submission used a separate delay - // mechanism, so doing it will be a behavior change. - return; - case ScheduledRedirection::historyNavigation: - // Don't report history navigations. - return; - } - ASSERT_NOT_REACHED(); - } + OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); + if (redirection && redirection->toldClient) + clientRedirectCancelledOrFinished(m_cancellingWithLoadInProgress); } void FrameLoader::completed() { RefPtr<Frame> protect(m_frame); for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->parentCompleted(); + child->loader()->startRedirectionTimer(); if (Frame* parent = m_frame->tree()->parent()) parent->loader()->checkCompleted(); if (m_frame->view()) @@ -2291,6 +2312,9 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHis void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const String& frameName, bool lockHistory, FrameLoadType newLoadType, PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState) { + if (m_unloadEventBeingDispatched) + return; + RefPtr<FormState> formState = prpFormState; bool isFormSubmission = formState; @@ -2330,6 +2354,7 @@ void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri if (shouldScrollToAnchor(isFormSubmission, newLoadType, newURL)) { oldDocumentLoader->setTriggeringAction(action); stopPolicyCheck(); + m_policyLoadType = newLoadType; checkNavigationPolicy(request, oldDocumentLoader.get(), formState.release(), callContinueFragmentScrollAfterNavigationPolicy, this); } else { @@ -2434,6 +2459,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t ASSERT(m_frame->view()); + if (m_unloadEventBeingDispatched) + return; + m_policyLoadType = type; RefPtr<FormState> formState = prpFormState; bool isFormSubmission = formState; @@ -2670,7 +2698,8 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const // // Or the target frame is: // - a top-level frame in the frame hierarchy and the active frame can - // navigate the target frame's opener per above. + // navigate the target frame's opener per above or it is the opener of + // the target frame. if (!targetFrame) return true; @@ -2685,6 +2714,10 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const if (targetFrame == m_frame->tree()->top()) return true; + // Let a frame navigate its opener if the opener is a top-level window. + if (!targetFrame->tree()->parent() && m_frame->loader()->opener() == targetFrame) + return true; + Document* activeDocument = m_frame->document(); ASSERT(activeDocument); const SecurityOrigin* activeSecurityOrigin = activeDocument->securityOrigin(); @@ -2900,7 +2933,7 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage) m_frame->document()->documentDidBecomeActive(); // Force a layout to update view size and thereby update scrollbars. - m_client->forceLayout(); + m_frame->view()->forceLayout(); const ResponseVector& responses = m_documentLoader->responses(); size_t count = responses.size(); @@ -3554,6 +3587,8 @@ void FrameLoader::checkLoadComplete() { ASSERT(m_client->hasWebView()); + m_shouldCallCheckLoadComplete = false; + // FIXME: Always traversing the entire frame tree is a bit inefficient, but // is currently needed in order to null out the previous history item for all frames. if (Page* page = m_frame->page()) @@ -4288,7 +4323,7 @@ void FrameLoader::pageHidden() { m_unloadEventBeingDispatched = true; if (m_frame->domWindow()) - m_frame->domWindow()->dispatchPageTransitionEvent(EventNames().pagehideEvent, true); + m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, true), m_frame->document()); m_unloadEventBeingDispatched = false; // Send pagehide event for subframes as well diff --git a/src/3rdparty/webkit/WebCore/loader/FrameLoader.h b/src/3rdparty/webkit/WebCore/loader/FrameLoader.h index 26206e6..4b4959b 100644 --- a/src/3rdparty/webkit/WebCore/loader/FrameLoader.h +++ b/src/3rdparty/webkit/WebCore/loader/FrameLoader.h @@ -35,6 +35,7 @@ #include "ResourceRequest.h" #include "ThreadableLoader.h" #include "Timer.h" +#include <wtf/Forward.h> namespace WebCore { @@ -411,15 +412,13 @@ namespace WebCore { void updateHistoryForAnchorScroll(); void redirectionTimerFired(Timer<FrameLoader>*); - void checkCompletedTimerFired(Timer<FrameLoader>*); - void checkLoadCompleteTimerFired(Timer<FrameLoader>*); + void checkTimerFired(Timer<FrameLoader>*); void cancelRedirection(bool newLoadInProgress = false); void started(); void completed(); - void parentCompleted(); bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback); bool loadPlugin(RenderPart*, const KURL&, const String& mimeType, @@ -485,7 +484,7 @@ namespace WebCore { bool shouldReloadToHandleUnreachableURL(DocumentLoader*); void handleUnimplementablePolicy(const ResourceError&); - void scheduleRedirection(ScheduledRedirection*); + void scheduleRedirection(PassOwnPtr<ScheduledRedirection>); void startRedirectionTimer(); void stopRedirectionTimer(); @@ -538,6 +537,7 @@ namespace WebCore { void scheduleCheckCompleted(); void scheduleCheckLoadComplete(); + void startCheckCompleteTimer(); KURL originalRequestURL() const; @@ -545,6 +545,9 @@ namespace WebCore { void saveScrollPositionAndViewStateToItem(HistoryItem*); + bool allAncestorsAreComplete() const; // including this + bool allChildrenAreComplete() const; // immediate children, not all descendants + Frame* m_frame; FrameLoaderClient* m_client; @@ -609,8 +612,9 @@ namespace WebCore { KURL m_submittedFormURL; Timer<FrameLoader> m_redirectionTimer; - Timer<FrameLoader> m_checkCompletedTimer; - Timer<FrameLoader> m_checkLoadCompleteTimer; + Timer<FrameLoader> m_checkTimer; + bool m_shouldCallCheckCompleted; + bool m_shouldCallCheckLoadComplete; Frame* m_opener; HashSet<Frame*> m_openedFrames; diff --git a/src/3rdparty/webkit/WebCore/loader/ImageDocument.cpp b/src/3rdparty/webkit/WebCore/loader/ImageDocument.cpp index d2b1dd6..8078ccd 100644 --- a/src/3rdparty/webkit/WebCore/loader/ImageDocument.cpp +++ b/src/3rdparty/webkit/WebCore/loader/ImageDocument.cpp @@ -70,7 +70,7 @@ private: { } - virtual void handleEvent(Event*, bool isWindowEvent); + virtual void handleEvent(Event*); ImageDocument* m_doc; }; @@ -358,7 +358,7 @@ bool ImageDocument::shouldShrinkToFit() const // -------- -void ImageEventListener::handleEvent(Event* event, bool) +void ImageEventListener::handleEvent(Event* event) { if (event->type() == eventNames().resizeEvent) m_doc->windowSizeChanged(); diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp index d18dcf2..ed27ba0 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp @@ -774,7 +774,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete() ASSERT(cacheStorage().isMaximumSizeReached() && m_calledReachedMaxAppCacheSize); } - RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache; + RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? RefPtr<ApplicationCache>(0) : m_newestCache; setNewestCache(m_cacheBeingUpdated.release()); if (cacheStorage().storeNewestCache(this)) { @@ -962,7 +962,7 @@ public: ASSERT(frame->loader()->documentLoader() == m_documentLoader.get()); - m_documentLoader->applicationCacheHost()->notifyEventListener(m_eventID); + m_documentLoader->applicationCacheHost()->notifyDOMApplicationCache(m_eventID); } private: diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp index 992f9e9..751efc1 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp @@ -227,10 +227,13 @@ void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplic m_domApplicationCache = domApplicationCache; } -void ApplicationCacheHost::notifyEventListener(EventID id) +void ApplicationCacheHost::notifyDOMApplicationCache(EventID id) { - if (m_domApplicationCache) - m_domApplicationCache->callEventListener(id); + if (m_domApplicationCache) { + ExceptionCode ec = 0; + m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec); + ASSERT(!ec); + } } void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group) diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h index cb68862..236013d 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h @@ -108,7 +108,7 @@ namespace WebCore { bool swapCache(); void setDOMApplicationCache(DOMApplicationCache* domApplicationCache); - void notifyEventListener(EventID id); + void notifyDOMApplicationCache(EventID id); private: bool isApplicationCacheEnabled(); diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp index dd0aed9..29c1bd5 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp @@ -91,73 +91,6 @@ ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const return m_frame->document(); } -void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool DOMApplicationCache::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - -void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener) -{ - ASSERT(m_frame); - - RefPtr<Event> event = Event::create(eventType, false, false); - if (listener) { - event->setTarget(this); - event->setCurrentTarget(this); - listener->handleEvent(event.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::EventID id) { switch (id) { @@ -182,27 +115,14 @@ const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::Event return eventNames().errorEvent; } -ApplicationCacheHost::EventID DOMApplicationCache::toEventID(const AtomicString& eventType) +EventTargetData* DOMApplicationCache::eventTargetData() { - if (eventType == eventNames().checkingEvent) - return ApplicationCacheHost::CHECKING_EVENT; - if (eventType == eventNames().errorEvent) - return ApplicationCacheHost::ERROR_EVENT; - if (eventType == eventNames().noupdateEvent) - return ApplicationCacheHost::NOUPDATE_EVENT; - if (eventType == eventNames().downloadingEvent) - return ApplicationCacheHost::DOWNLOADING_EVENT; - if (eventType == eventNames().progressEvent) - return ApplicationCacheHost::PROGRESS_EVENT; - if (eventType == eventNames().updatereadyEvent) - return ApplicationCacheHost::UPDATEREADY_EVENT; - if (eventType == eventNames().cachedEvent) - return ApplicationCacheHost::CACHED_EVENT; - if (eventType == eventNames().obsoleteEvent) - return ApplicationCacheHost::OBSOLETE_EVENT; - - ASSERT_NOT_REACHED(); - return ApplicationCacheHost::ERROR_EVENT; + return &m_eventTargetData; +} + +EventTargetData* DOMApplicationCache::ensureEventTargetData() +{ + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h index 09e9a03..077cae0 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h @@ -30,8 +30,9 @@ #include "ApplicationCacheHost.h" #include "AtomicStringHash.h" -#include "EventTarget.h" #include "EventListener.h" +#include "EventNames.h" +#include "EventTarget.h" #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -55,72 +56,39 @@ public: void update(ExceptionCode&); void swapCache(ExceptionCode&); - // Event listener attributes by EventID - - void setAttributeEventListener(ApplicationCacheHost::EventID id, PassRefPtr<EventListener> eventListener) { m_attributeEventListeners[id] = eventListener; } - EventListener* getAttributeEventListener(ApplicationCacheHost::EventID id) const { return m_attributeEventListeners[id].get(); } - void clearAttributeEventListener(ApplicationCacheHost::EventID id) { m_attributeEventListeners[id] = 0; } - void callEventListener(ApplicationCacheHost::EventID id) { callListener(toEventType(id), getAttributeEventListener(id)); } - // EventTarget impl - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } - using RefCounted<DOMApplicationCache>::ref; using RefCounted<DOMApplicationCache>::deref; // Explicitly named attribute event listener helpers - void setOnchecking(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::CHECKING_EVENT, listener); } - EventListener* onchecking() const { return getAttributeEventListener(ApplicationCacheHost::CHECKING_EVENT); } - - void setOnerror(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::ERROR_EVENT, listener);} - EventListener* onerror() const { return getAttributeEventListener(ApplicationCacheHost::ERROR_EVENT); } - - void setOnnoupdate(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::NOUPDATE_EVENT, listener); } - EventListener* onnoupdate() const { return getAttributeEventListener(ApplicationCacheHost::NOUPDATE_EVENT); } - - void setOndownloading(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::DOWNLOADING_EVENT, listener); } - EventListener* ondownloading() const { return getAttributeEventListener(ApplicationCacheHost::DOWNLOADING_EVENT); } - - void setOnprogress(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::PROGRESS_EVENT, listener); } - EventListener* onprogress() const { return getAttributeEventListener(ApplicationCacheHost::PROGRESS_EVENT); } - - void setOnupdateready(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::UPDATEREADY_EVENT, listener); } - EventListener* onupdateready() const { return getAttributeEventListener(ApplicationCacheHost::UPDATEREADY_EVENT); } - - void setOncached(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::CACHED_EVENT, listener); } - EventListener* oncached() const { return getAttributeEventListener(ApplicationCacheHost::CACHED_EVENT); } - - void setOnobsolete(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::OBSOLETE_EVENT, listener); } - EventListener* onobsolete() const { return getAttributeEventListener(ApplicationCacheHost::OBSOLETE_EVENT); } + DEFINE_ATTRIBUTE_EVENT_LISTENER(checking); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cached); + DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete); virtual ScriptExecutionContext* scriptExecutionContext() const; DOMApplicationCache* toDOMApplicationCache() { return this; } static const AtomicString& toEventType(ApplicationCacheHost::EventID id); - static ApplicationCacheHost::EventID toEventID(const AtomicString& eventType); private: DOMApplicationCache(Frame*); - void callListener(const AtomicString& eventType, EventListener*); - virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); ApplicationCacheHost* applicationCacheHost() const; - - RefPtr<EventListener> m_attributeEventListeners[ApplicationCacheHost::OBSOLETE_EVENT + 1]; - - EventListenersMap m_eventListeners; Frame* m_frame; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl index ebc1d19..dd5468a 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl @@ -27,7 +27,7 @@ module offline { interface [ Conditional=OFFLINE_WEB_APPLICATIONS, - CustomMarkFunction + EventTarget ] DOMApplicationCache { // update status const unsigned short UNCACHED = 0; diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLElement.cpp b/src/3rdparty/webkit/WebCore/mathml/MathMLElement.cpp new file mode 100644 index 0000000..14febe5 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLElement.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#if ENABLE(MATHML) + +#include "MathMLElement.h" + +#include "MathMLNames.h" +#include "RenderObject.h" + +namespace WebCore { + +using namespace MathMLNames; + +MathMLElement::MathMLElement(const QualifiedName& tagName, Document* document) + : StyledElement(tagName, document, CreateElementZeroRefCount) +{ +} + +PassRefPtr<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document* document) +{ + return new MathMLElement(tagName, document); +} + +RenderObject* MathMLElement::createRenderer(RenderArena*, RenderStyle* style) +{ + return RenderObject::createObject(this, style); +} + + +} + +#endif // ENABLE(MATHML) diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLElement.h b/src/3rdparty/webkit/WebCore/mathml/MathMLElement.h new file mode 100644 index 0000000..b00af47 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLElement.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef MathMLElement_h +#define MathMLElement_h + +#if ENABLE(MATHML) +#include "StyledElement.h" + +namespace WebCore { + +class MathMLElement : public StyledElement { +public: + static PassRefPtr<MathMLElement> create(const QualifiedName& tagName, Document*); + + virtual bool isMathMLElement() const { return true; } + + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + +protected: + MathMLElement(const QualifiedName& tagName, Document*); + +}; + +} + +#endif // ENABLE(MATHML) +#endif // MathMLElement_h diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.cpp b/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.cpp new file mode 100644 index 0000000..2bb02f6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#if ENABLE(MATHML) + +#include "MathMLInlineContainerElement.h" + +#include "MathMLNames.h" +#include "RenderObject.h" + +namespace WebCore { + +using namespace MathMLNames; + +MathMLInlineContainerElement::MathMLInlineContainerElement(const QualifiedName& tagName, Document* document) + : MathMLElement(tagName, document) +{ +} + +PassRefPtr<MathMLInlineContainerElement> MathMLInlineContainerElement::create(const QualifiedName& tagName, Document* document) +{ + return new MathMLInlineContainerElement(tagName, document); +} + +RenderObject* MathMLInlineContainerElement::createRenderer(RenderArena *, RenderStyle* style) +{ + // FIXME: This method will contain the specialized renderers based on element name + return RenderObject::createObject(this, style); +} + + +} + +#endif // ENABLE(MATHML) + diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.h b/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.h new file mode 100644 index 0000000..4529d3b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLInlineContainerElement.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef MathMLInlineContainerElement_h +#define MathMLInlineContainerElement_h + +#if ENABLE(MATHML) +#include "MathMLElement.h" + +namespace WebCore { + +class MathMLInlineContainerElement : public MathMLElement { +public: + static PassRefPtr<MathMLInlineContainerElement> create(const QualifiedName& tagName, Document*); + + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + +protected: + MathMLInlineContainerElement(const QualifiedName& tagName, Document*); + +}; + +} + +#endif // ENABLE(MATHML) +#endif // MathMLInlineContainerElement_h diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.cpp b/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.cpp new file mode 100644 index 0000000..8b083f4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#if ENABLE(MATHML) + +#include "MathMLMathElement.h" + +#include "MathMLNames.h" +#include "RenderObject.h" + +namespace WebCore { + +using namespace MathMLNames; + +MathMLMathElement::MathMLMathElement(const QualifiedName& tagName, Document* document) + : MathMLInlineContainerElement(tagName, document) +{ +} + +PassRefPtr<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tagName, Document* document) +{ + return new MathMLMathElement(tagName, document); +} + +} + +#endif // ENABLE(MATHML) diff --git a/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.h b/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.h new file mode 100644 index 0000000..f363cd2 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/MathMLMathElement.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef MathMLMathElement_h +#define MathMLMathElement_h + +#if ENABLE(MATHML) +#include "MathMLInlineContainerElement.h" + +namespace WebCore { + +class MathMLMathElement : public MathMLInlineContainerElement { +public: + static PassRefPtr<MathMLMathElement> create(const QualifiedName& tagName, Document*); + +protected: + MathMLMathElement(const QualifiedName& tagName, Document*); + +}; + +} + +#endif // ENABLE(MATHML) +#endif // MathMLMathElement_h diff --git a/src/3rdparty/webkit/WebCore/mathml/mathtags.in b/src/3rdparty/webkit/WebCore/mathml/mathtags.in new file mode 100644 index 0000000..8704dbf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/mathml/mathtags.in @@ -0,0 +1,21 @@ +namespace="MathML" +namespaceURI="http://www.w3.org/1998/Math/MathML" +guardFactoryWith="ENABLE(MATHML)" +exportStrings + +math +mfrac interfaceName=MathMLInlineContainerElement +mfenced interfaceName=MathMLInlineContainerElement +msubsup interfaceName=MathMLInlineContainerElement +mrow interfaceName=MathMLInlineContainerElement +mover interfaceName=MathMLInlineContainerElement +munder interfaceName=MathMLInlineContainerElement +munderover interfaceName=MathMLInlineContainerElement +msqrt interfaceName=MathMLInlineContainerElement +mroot interfaceName=MathMLInlineContainerElement +mi interfaceName=MathMLElement, createWithNew +mn interfaceName=MathMLElement, createWithNew +mo interfaceName=MathMLElement, createWithNew +msub interfaceName=MathMLElement, createWithNew +msup interfaceName=MathMLElement, createWithNew + diff --git a/src/3rdparty/webkit/WebCore/notifications/Notification.cpp b/src/3rdparty/webkit/WebCore/notifications/Notification.cpp index 61ad1f3..8dd168f 100644 --- a/src/3rdparty/webkit/WebCore/notifications/Notification.cpp +++ b/src/3rdparty/webkit/WebCore/notifications/Notification.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * 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 @@ -96,137 +97,14 @@ void Notification::cancel() m_presenter->cancel(this); } -EventListener* Notification::ondisplay() const +EventTargetData* Notification::eventTargetData() { - return getAttributeEventListener("display"); + return &m_eventTargetData; } -void Notification::setOndisplay(PassRefPtr<EventListener> eventListener) +EventTargetData* Notification::ensureEventTargetData() { - setAttributeEventListener("display", eventListener); -} - -EventListener* Notification::onerror() const -{ - return getAttributeEventListener(eventNames().errorEvent); -} - -void Notification::setOnerror(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* Notification::onclose() const -{ - return getAttributeEventListener(eventNames().closeEvent); -} - -void Notification::setOnclose(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().closeEvent, eventListener); -} - -EventListener* Notification::getAttributeEventListener(const AtomicString& eventType) const -{ - const RegisteredEventListenerVector& listeners = m_eventListeners; - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listeners[i]; - if (r.eventType() == eventType && r.listener()->isAttribute()) - return r.listener(); - } - return 0; -} - -void Notification::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) -{ - clearAttributeEventListener(eventType); - if (listener) - addEventListener(eventType, listener, false); -} - -void Notification::clearAttributeEventListener(const AtomicString& eventType) -{ - RegisteredEventListenerVector* listeners = &m_eventListeners; - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listeners->at(i); - if (r.eventType() != eventType || !r.listener()->isAttribute()) - continue; - - r.setRemoved(true); - listeners->remove(i); - return; - } -} - -void Notification::dispatchDisplayEvent() -{ - RefPtr<Event> event = Event::create("display", false, true); - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - -void Notification::dispatchErrorEvent() -{ - RefPtr<Event> event = Event::create(eventNames().errorEvent, false, true); - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - -void Notification::dispatchCloseEvent() -{ - RefPtr<Event> event = Event::create(eventNames().closeEvent, false, true); - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - -void Notification::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) -{ - RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture); - m_eventListeners.append(registeredListener); -} - -void Notification::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) -{ - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *m_eventListeners[i]; - if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) { - r.setRemoved(true); - m_eventListeners.remove(i); - return; - } - } -} - -void Notification::handleEvent(PassRefPtr<Event> event, bool useCapture) -{ - RegisteredEventListenerVector listenersCopy = m_eventListeners; - size_t size = listenersCopy.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listenersCopy[i]; - if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed()) - r.listener()->handleEvent(event.get()); - } -} - -bool Notification::dispatchEvent(PassRefPtr<Event> inEvent, ExceptionCode&) -{ - RefPtr<Event> event(inEvent); - - event->setEventPhase(Event::AT_TARGET); - event->setCurrentTarget(this); - - handleEvent(event.get(), true); - if (!event->propagationStopped()) { - handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/notifications/Notification.h b/src/3rdparty/webkit/WebCore/notifications/Notification.h index baae4ee..6545579 100644 --- a/src/3rdparty/webkit/WebCore/notifications/Notification.h +++ b/src/3rdparty/webkit/WebCore/notifications/Notification.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * 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 @@ -35,6 +36,7 @@ #include "AtomicStringHash.h" #include "Event.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "ExceptionCode.h" #include "KURL.h" @@ -65,33 +67,17 @@ namespace WebCore { KURL url() { return m_notificationURL; } NotificationContents& contents() { return m_contents; } - EventListener* ondisplay() const; - void setOndisplay(PassRefPtr<EventListener> eventListener); - EventListener* onerror() const; - void setOnerror(PassRefPtr<EventListener> eventListener); - EventListener* onclose() const; - void setOnclose(PassRefPtr<EventListener> eventListener); + DEFINE_ATTRIBUTE_EVENT_LISTENER(display); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(close); using RefCounted<Notification>::ref; using RefCounted<Notification>::deref; - // Dispatching of events on the notification. The presenter should call these when events occur. - void dispatchDisplayEvent(); - void dispatchErrorEvent(); - void dispatchCloseEvent(); - // EventTarget interface virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); } - virtual void addEventListener(const AtomicString&, PassRefPtr<EventListener>, bool); - virtual void removeEventListener(const AtomicString&, EventListener*, bool); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); virtual Notification* toNotification() { return this; } - // These methods are for onEvent style listeners. - EventListener* getAttributeEventListener(const AtomicString&) const; - void setAttributeEventListener(const AtomicString&, PassRefPtr<EventListener>); - void clearAttributeEventListener(const AtomicString&); - private: Notification(const String& url, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider); Notification(const NotificationContents& fields, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider); @@ -99,8 +85,8 @@ namespace WebCore { // EventTarget interface virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } - - void handleEvent(PassRefPtr<Event> event, bool useCapture); + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); bool m_isHTML; KURL m_notificationURL; @@ -108,9 +94,9 @@ namespace WebCore { bool m_isShowing; - RegisteredEventListenerVector m_eventListeners; - NotificationPresenter* m_presenter; + + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/notifications/Notification.idl b/src/3rdparty/webkit/WebCore/notifications/Notification.idl index eca2eb4..ec6a9c8 100644 --- a/src/3rdparty/webkit/WebCore/notifications/Notification.idl +++ b/src/3rdparty/webkit/WebCore/notifications/Notification.idl @@ -31,7 +31,8 @@ module threads { interface [ - Conditional=NOTIFICATIONS + Conditional=NOTIFICATIONS, + EventTarget ] Notification { void show(); void cancel(); diff --git a/src/3rdparty/webkit/WebCore/page/Chrome.cpp b/src/3rdparty/webkit/WebCore/page/Chrome.cpp index a16db68..96f0fb7 100644 --- a/src/3rdparty/webkit/WebCore/page/Chrome.cpp +++ b/src/3rdparty/webkit/WebCore/page/Chrome.cpp @@ -87,9 +87,9 @@ IntRect Chrome::windowToScreen(const IntRect& rect) const return m_client->windowToScreen(rect); } -PlatformWidget Chrome::platformWindow() const +PlatformPageClient Chrome::platformPageClient() const { - return m_client->platformWindow(); + return m_client->platformPageClient(); } void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const diff --git a/src/3rdparty/webkit/WebCore/page/Chrome.h b/src/3rdparty/webkit/WebCore/page/Chrome.h index 79d3eca..033311d 100644 --- a/src/3rdparty/webkit/WebCore/page/Chrome.h +++ b/src/3rdparty/webkit/WebCore/page/Chrome.h @@ -63,7 +63,7 @@ namespace WebCore { virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; - virtual PlatformWidget platformWindow() const; + virtual PlatformPageClient platformPageClient() const; virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const; virtual void scrollbarsModeDidChange() const; diff --git a/src/3rdparty/webkit/WebCore/page/ChromeClient.h b/src/3rdparty/webkit/WebCore/page/ChromeClient.h index 2a1e991..2d11275 100644 --- a/src/3rdparty/webkit/WebCore/page/ChromeClient.h +++ b/src/3rdparty/webkit/WebCore/page/ChromeClient.h @@ -128,7 +128,7 @@ namespace WebCore { virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) = 0; virtual IntPoint screenToWindow(const IntPoint&) const = 0; virtual IntRect windowToScreen(const IntRect&) const = 0; - virtual PlatformWidget platformWindow() const = 0; + virtual PlatformPageClient platformPageClient() const = 0; virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0; virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0; // Currently only Mac has a non empty implementation. // End methods used by HostWindow. diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp index 783f93d..809d541 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp @@ -105,7 +105,7 @@ public: PassRefPtr<MessageEvent> event(ScriptExecutionContext* context) { OwnPtr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, m_channels.release()); - return MessageEvent::create(m_message, m_origin, "", m_source, messagePorts.release()); + return MessageEvent::create(messagePorts.release(), m_message, m_origin, "", m_source); } SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } @@ -123,83 +123,36 @@ private: RefPtr<SecurityOrigin> m_targetOrigin; }; -typedef HashMap<DOMWindow*, RegisteredEventListenerVector*> DOMWindowRegisteredEventListenerMap; +typedef HashCountedSet<DOMWindow*> DOMWindowSet; -static DOMWindowRegisteredEventListenerMap& pendingUnloadEventListenerMap() +static DOMWindowSet& windowsWithUnloadEventListeners() { - DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ()); - return eventListenerMap; + DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ()); + return windowsWithUnloadEventListeners; } -static DOMWindowRegisteredEventListenerMap& pendingBeforeUnloadEventListenerMap() +static DOMWindowSet& windowsWithBeforeUnloadEventListeners() { - DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ()); - return eventListenerMap; + DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ()); + return windowsWithBeforeUnloadEventListeners; } -static bool allowsPendingBeforeUnloadListeners(DOMWindow* window) +static bool allowsBeforeUnloadListeners(DOMWindow* window) { ASSERT_ARG(window, window); Frame* frame = window->frame(); + if (!frame) + return false; Page* page = frame->page(); - return page && frame == page->mainFrame(); -} - -static void addPendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener) -{ - ASSERT_ARG(window, window); - ASSERT_ARG(listener, listener); - - if (map.isEmpty()) - disableSuddenTermination(); - - pair<DOMWindowRegisteredEventListenerMap::iterator, bool> result = map.add(window, 0); - if (result.second) - result.first->second = new RegisteredEventListenerVector; - result.first->second->append(listener); -} - -static void removePendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener) -{ - ASSERT_ARG(window, window); - ASSERT_ARG(listener, listener); - - DOMWindowRegisteredEventListenerMap::iterator it = map.find(window); - ASSERT(it != map.end()); - - RegisteredEventListenerVector* listeners = it->second; - size_t index = listeners->find(listener); - ASSERT(index != WTF::notFound); - listeners->remove(index); - - if (!listeners->isEmpty()) - return; - - map.remove(it); - delete listeners; - - if (map.isEmpty()) - enableSuddenTermination(); -} - -static void removePendingEventListeners(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window) -{ - ASSERT_ARG(window, window); - - RegisteredEventListenerVector* listeners = map.take(window); - if (!listeners) - return; - - delete listeners; - - if (map.isEmpty()) - enableSuddenTermination(); + if (!page) + return false; + return frame == page->mainFrame(); } bool DOMWindow::dispatchAllPendingBeforeUnloadEvents() { - DOMWindowRegisteredEventListenerMap& map = pendingBeforeUnloadEventListenerMap(); - if (map.isEmpty()) + DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); + if (set.isEmpty()) return true; static bool alreadyDispatched = false; @@ -208,20 +161,21 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents() return true; Vector<RefPtr<DOMWindow> > windows; - DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end(); - for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it) + DOMWindowSet::iterator end = set.end(); + for (DOMWindowSet::iterator it = set.begin(); it != end; ++it) windows.append(it->first); size_t size = windows.size(); for (size_t i = 0; i < size; ++i) { DOMWindow* window = windows[i].get(); - RegisteredEventListenerVector* listeners = map.get(window); - if (!listeners) + if (!set.contains(window)) continue; - RegisteredEventListenerVector listenersCopy = *listeners; Frame* frame = window->frame(); - if (!frame->shouldClose(&listenersCopy)) + if (!frame) + continue; + + if (!frame->shouldClose()) return false; } @@ -234,14 +188,13 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents() unsigned DOMWindow::pendingUnloadEventListeners() const { - RegisteredEventListenerVector* listeners = pendingUnloadEventListenerMap().get(const_cast<DOMWindow*>(this)); - return listeners ? listeners->size() : 0; + return windowsWithUnloadEventListeners().count(const_cast<DOMWindow*>(this)); } void DOMWindow::dispatchAllPendingUnloadEvents() { - DOMWindowRegisteredEventListenerMap& map = pendingUnloadEventListenerMap(); - if (map.isEmpty()) + DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); + if (set.isEmpty()) return; static bool alreadyDispatched = false; @@ -250,19 +203,18 @@ void DOMWindow::dispatchAllPendingUnloadEvents() return; Vector<RefPtr<DOMWindow> > windows; - DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end(); - for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it) + DOMWindowSet::iterator end = set.end(); + for (DOMWindowSet::iterator it = set.begin(); it != end; ++it) windows.append(it->first); size_t size = windows.size(); for (size_t i = 0; i < size; ++i) { DOMWindow* window = windows[i].get(); - RegisteredEventListenerVector* listeners = map.get(window); - if (!listeners) + if (!set.contains(window)) continue; - RegisteredEventListenerVector listenersCopy = *listeners; - window->dispatchPageTransitionEvent(EventNames().pagehideEvent, false); - window->dispatchUnloadEvent(&listenersCopy); + + window->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, false), window->document()); + window->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window->document()); } enableSuddenTermination(); @@ -376,8 +328,8 @@ DOMWindow::~DOMWindow() if (m_frame) m_frame->clearFormerDOMWindow(this); - removePendingEventListeners(pendingUnloadEventListenerMap(), this); - removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this); + windowsWithUnloadEventListeners().clear(this); + windowsWithBeforeUnloadEventListeners().clear(this); } ScriptExecutionContext* DOMWindow::scriptExecutionContext() const @@ -462,6 +414,16 @@ void DOMWindow::clear() #endif } +#if ENABLE(ORIENTATION_EVENTS) +int DOMWindow::orientation() const +{ + if (!m_frame) + return 0; + + return m_frame->orientation(); +} +#endif + Screen* DOMWindow::screen() const { if (!m_screen) @@ -682,8 +644,7 @@ void DOMWindow::postMessageTimerFired(PostMessageTimer* t) } } - ExceptionCode ec = 0; - dispatchEvent(timer->event(document()), ec); + dispatchEvent(timer->event(document())); } DOMSelection* DOMWindow::getSelection() @@ -1245,104 +1206,38 @@ void DOMWindow::clearInterval(int timeoutId) DOMTimer::removeById(scriptExecutionContext(), timeoutId); } -void DOMWindow::handleEvent(Event* event, bool useCapture, RegisteredEventListenerVector* alternateListeners) +bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - RegisteredEventListenerVector& listeners = (alternateListeners ? *alternateListeners : m_eventListeners); - if (listeners.isEmpty()) - return; - - // If any HTML event listeners are registered on the window, dispatch them here. - RegisteredEventListenerVector listenersCopy = listeners; - size_t size = listenersCopy.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listenersCopy[i]; - if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed()) - r.listener()->handleEvent(event, true); - } -} + if (!EventTarget::addEventListener(eventType, listener, useCapture)) + return false; -void DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) -{ - // Remove existing identical listener set with identical arguments. - // The DOM 2 spec says that "duplicate instances are discarded" in this case. - removeEventListener(eventType, listener.get(), useCapture); if (Document* document = this->document()) document->addListenerTypeIfNeeded(eventType); - RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture); - m_eventListeners.append(registeredListener); - if (eventType == eventNames().unloadEvent) - addPendingEventListener(pendingUnloadEventListenerMap(), this, registeredListener.get()); - else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this)) - addPendingEventListener(pendingBeforeUnloadEventListenerMap(), this, registeredListener.get()); -} - -void DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) -{ - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *m_eventListeners[i]; - if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) { - if (eventType == eventNames().unloadEvent) - removePendingEventListener(pendingUnloadEventListenerMap(), this, &r); - else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this)) - removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r); - r.setRemoved(true); - m_eventListeners.remove(i); - return; - } - } -} - -bool DOMWindow::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) -{ - ASSERT(!eventDispatchForbidden()); - - RefPtr<Event> event = e; - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - RefPtr<DOMWindow> protect(this); - - event->setTarget(this); - event->setCurrentTarget(this); + windowsWithUnloadEventListeners().add(this); + else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this)) + windowsWithBeforeUnloadEventListeners().add(this); - handleEvent(event.get(), true); - handleEvent(event.get(), false); - - return !event->defaultPrevented(); -} - -void DOMWindow::dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - dispatchEvent(Event::create(eventType, canBubble, cancelable), ec); + return true; } -// This function accommodates the Firefox quirk of dispatching the load, unload and -// beforeunload events on the window, but setting event.target to be the Document. -inline void DOMWindow::dispatchEventWithDocumentAsTarget(PassRefPtr<Event> e, RegisteredEventListenerVector* alternateEventListeners) +bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - ASSERT(!eventDispatchForbidden()); - - RefPtr<Event> event = e; - RefPtr<DOMWindow> protect(this); - RefPtr<Document> document = this->document(); + if (!EventTarget::removeEventListener(eventType, listener, useCapture)) + return false; - event->setTarget(document); - event->setCurrentTarget(this); + if (eventType == eventNames().unloadEvent) + windowsWithUnloadEventListeners().remove(this); + else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this)) + windowsWithBeforeUnloadEventListeners().remove(this); - handleEvent(event.get(), true, alternateEventListeners); - handleEvent(event.get(), false, alternateEventListeners); + return true; } void DOMWindow::dispatchLoadEvent() { - dispatchEventWithDocumentAsTarget(Event::create(eventNames().loadEvent, false, false)); + dispatchEvent(Event::create(eventNames().loadEvent, false, false), document()); // For load events, send a separate load event to the enclosing frame only. // This is a DOM extension and is independent of bubbling/capturing rules of @@ -1355,747 +1250,44 @@ void DOMWindow::dispatchLoadEvent() } } -void DOMWindow::dispatchUnloadEvent(RegisteredEventListenerVector* alternateEventListeners) +bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget) { - dispatchEventWithDocumentAsTarget(Event::create(eventNames().unloadEvent, false, false), alternateEventListeners); -} + RefPtr<EventTarget> protect = this; + RefPtr<Event> event = prpEvent; -PassRefPtr<BeforeUnloadEvent> DOMWindow::dispatchBeforeUnloadEvent(RegisteredEventListenerVector* alternateEventListeners) -{ - RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create(); - dispatchEventWithDocumentAsTarget(beforeUnloadEvent.get(), alternateEventListeners); - return beforeUnloadEvent.release(); -} + event->setTarget(prpTarget ? prpTarget : this); + event->setCurrentTarget(this); + event->setEventPhase(Event::AT_TARGET); -void DOMWindow::dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted) -{ - dispatchEventWithDocumentAsTarget(PageTransitionEvent::create(eventType, persisted)); + return fireEventListeners(event.get()); } void DOMWindow::removeAllEventListeners() { - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) - m_eventListeners[i]->setRemoved(true); - m_eventListeners.clear(); - - removePendingEventListeners(pendingUnloadEventListenerMap(), this); - removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this); -} - -bool DOMWindow::hasEventListener(const AtomicString& eventType) -{ - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) { - if (m_eventListeners[i]->eventType() == eventType) - return true; - } - return false; -} - -void DOMWindow::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) -{ - clearAttributeEventListener(eventType); - if (listener) - addEventListener(eventType, listener, false); -} - -void DOMWindow::clearAttributeEventListener(const AtomicString& eventType) -{ - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *m_eventListeners[i]; - if (r.eventType() == eventType && r.listener()->isAttribute()) { - if (eventType == eventNames().unloadEvent) - removePendingEventListener(pendingUnloadEventListenerMap(), this, &r); - else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this)) - removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r); - r.setRemoved(true); - m_eventListeners.remove(i); - return; - } - } -} - -EventListener* DOMWindow::getAttributeEventListener(const AtomicString& eventType) const -{ - size_t size = m_eventListeners.size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *m_eventListeners[i]; - if (r.eventType() == eventType && r.listener()->isAttribute()) - return r.listener(); - } - return 0; -} - -EventListener* DOMWindow::onabort() const -{ - return getAttributeEventListener(eventNames().abortEvent); -} - -void DOMWindow::setOnabort(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().abortEvent, eventListener); -} - -EventListener* DOMWindow::onblur() const -{ - return getAttributeEventListener(eventNames().blurEvent); -} - -void DOMWindow::setOnblur(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* DOMWindow::onchange() const -{ - return getAttributeEventListener(eventNames().changeEvent); -} - -void DOMWindow::setOnchange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().changeEvent, eventListener); -} - -EventListener* DOMWindow::onclick() const -{ - return getAttributeEventListener(eventNames().clickEvent); -} - -void DOMWindow::setOnclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().clickEvent, eventListener); -} - -EventListener* DOMWindow::ondblclick() const -{ - return getAttributeEventListener(eventNames().dblclickEvent); -} - -void DOMWindow::setOndblclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dblclickEvent, eventListener); -} - -EventListener* DOMWindow::ondrag() const -{ - return getAttributeEventListener(eventNames().dragEvent); -} - -void DOMWindow::setOndrag(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragEvent, eventListener); -} - -EventListener* DOMWindow::ondragend() const -{ - return getAttributeEventListener(eventNames().dragendEvent); -} - -void DOMWindow::setOndragend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragendEvent, eventListener); -} - -EventListener* DOMWindow::ondragenter() const -{ - return getAttributeEventListener(eventNames().dragenterEvent); -} - -void DOMWindow::setOndragenter(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragenterEvent, eventListener); -} - -EventListener* DOMWindow::ondragleave() const -{ - return getAttributeEventListener(eventNames().dragleaveEvent); -} - -void DOMWindow::setOndragleave(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragleaveEvent, eventListener); -} - -EventListener* DOMWindow::ondragover() const -{ - return getAttributeEventListener(eventNames().dragoverEvent); -} - -void DOMWindow::setOndragover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragoverEvent, eventListener); -} - -EventListener* DOMWindow::ondragstart() const -{ - return getAttributeEventListener(eventNames().dragstartEvent); -} - -void DOMWindow::setOndragstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragstartEvent, eventListener); -} - -EventListener* DOMWindow::ondrop() const -{ - return getAttributeEventListener(eventNames().dropEvent); -} - -void DOMWindow::setOndrop(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dropEvent, eventListener); -} - -EventListener* DOMWindow::onerror() const -{ - return getAttributeEventListener(eventNames().errorEvent); -} - -void DOMWindow::setOnerror(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* DOMWindow::onfocus() const -{ - return getAttributeEventListener(eventNames().focusEvent); -} - -void DOMWindow::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* DOMWindow::onhashchange() const -{ - return getAttributeEventListener(eventNames().hashchangeEvent); -} - -void DOMWindow::setOnhashchange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().hashchangeEvent, eventListener); -} - -EventListener* DOMWindow::onkeydown() const -{ - return getAttributeEventListener(eventNames().keydownEvent); -} - -void DOMWindow::setOnkeydown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keydownEvent, eventListener); -} - -EventListener* DOMWindow::onkeypress() const -{ - return getAttributeEventListener(eventNames().keypressEvent); -} - -void DOMWindow::setOnkeypress(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keypressEvent, eventListener); -} - -EventListener* DOMWindow::onkeyup() const -{ - return getAttributeEventListener(eventNames().keyupEvent); -} - -void DOMWindow::setOnkeyup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keyupEvent, eventListener); -} - -EventListener* DOMWindow::onload() const -{ - return getAttributeEventListener(eventNames().loadEvent); -} - -void DOMWindow::setOnload(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* DOMWindow::onmousedown() const -{ - return getAttributeEventListener(eventNames().mousedownEvent); -} - -void DOMWindow::setOnmousedown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousedownEvent, eventListener); -} - -EventListener* DOMWindow::onmousemove() const -{ - return getAttributeEventListener(eventNames().mousemoveEvent); -} - -void DOMWindow::setOnmousemove(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousemoveEvent, eventListener); -} - -EventListener* DOMWindow::onmouseout() const -{ - return getAttributeEventListener(eventNames().mouseoutEvent); -} - -void DOMWindow::setOnmouseout(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoutEvent, eventListener); -} + EventTarget::removeAllEventListeners(); -EventListener* DOMWindow::onmouseover() const -{ - return getAttributeEventListener(eventNames().mouseoverEvent); + windowsWithUnloadEventListeners().clear(this); + windowsWithBeforeUnloadEventListeners().clear(this); } -void DOMWindow::setOnmouseover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoverEvent, eventListener); -} - -EventListener* DOMWindow::onmouseup() const -{ - return getAttributeEventListener(eventNames().mouseupEvent); -} - -void DOMWindow::setOnmouseup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseupEvent, eventListener); -} - -EventListener* DOMWindow::onmousewheel() const -{ - return getAttributeEventListener(eventNames().mousewheelEvent); -} - -void DOMWindow::setOnmousewheel(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousewheelEvent, eventListener); -} - -EventListener* DOMWindow::onoffline() const -{ - return getAttributeEventListener(eventNames().offlineEvent); -} - -void DOMWindow::setOnoffline(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().offlineEvent, eventListener); -} - -EventListener* DOMWindow::ononline() const -{ - return getAttributeEventListener(eventNames().onlineEvent); -} - -void DOMWindow::setOnonline(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().onlineEvent, eventListener); -} - -EventListener* DOMWindow::onpagehide() const -{ - return getAttributeEventListener(eventNames().pagehideEvent); -} - -void DOMWindow::setOnpagehide(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().pagehideEvent, eventListener); -} - -EventListener* DOMWindow::onpageshow() const -{ - return getAttributeEventListener(eventNames().pageshowEvent); -} - -void DOMWindow::setOnpageshow(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().pageshowEvent, eventListener); -} - -EventListener* DOMWindow::onreset() const -{ - return getAttributeEventListener(eventNames().resetEvent); -} - -void DOMWindow::setOnreset(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().resetEvent, eventListener); -} - -EventListener* DOMWindow::onresize() const -{ - return getAttributeEventListener(eventNames().resizeEvent); -} - -void DOMWindow::setOnresize(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().resizeEvent, eventListener); -} - -EventListener* DOMWindow::onscroll() const -{ - return getAttributeEventListener(eventNames().scrollEvent); -} - -void DOMWindow::setOnscroll(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().scrollEvent, eventListener); -} - -EventListener* DOMWindow::onsearch() const -{ - return getAttributeEventListener(eventNames().searchEvent); -} - -void DOMWindow::setOnsearch(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().searchEvent, eventListener); -} - -EventListener* DOMWindow::onselect() const -{ - return getAttributeEventListener(eventNames().selectEvent); -} - -void DOMWindow::setOnselect(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().selectEvent, eventListener); -} - -EventListener* DOMWindow::onstorage() const -{ - return getAttributeEventListener(eventNames().storageEvent); -} - -void DOMWindow::setOnstorage(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().storageEvent, eventListener); -} - -EventListener* DOMWindow::onsubmit() const -{ - return getAttributeEventListener(eventNames().submitEvent); -} - -void DOMWindow::setOnsubmit(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().submitEvent, eventListener); -} - -EventListener* DOMWindow::onunload() const -{ - return getAttributeEventListener(eventNames().unloadEvent); -} - -void DOMWindow::setOnunload(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().unloadEvent, eventListener); -} - -EventListener* DOMWindow::onbeforeunload() const -{ - return getAttributeEventListener(eventNames().beforeunloadEvent); -} - -void DOMWindow::setOnbeforeunload(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforeunloadEvent, eventListener); -} - -EventListener* DOMWindow::onwebkitanimationstart() const -{ - return getAttributeEventListener(eventNames().webkitAnimationStartEvent); -} - -void DOMWindow::setOnwebkitanimationstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().webkitAnimationStartEvent, eventListener); -} - -EventListener* DOMWindow::onwebkitanimationiteration() const -{ - return getAttributeEventListener(eventNames().webkitAnimationIterationEvent); -} - -void DOMWindow::setOnwebkitanimationiteration(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().webkitAnimationIterationEvent, eventListener); -} - -EventListener* DOMWindow::onwebkitanimationend() const -{ - return getAttributeEventListener(eventNames().webkitAnimationEndEvent); -} - -void DOMWindow::setOnwebkitanimationend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().webkitAnimationEndEvent, eventListener); -} - -EventListener* DOMWindow::onwebkittransitionend() const -{ - return getAttributeEventListener(eventNames().webkitTransitionEndEvent); -} - -void DOMWindow::setOnwebkittransitionend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().webkitTransitionEndEvent, eventListener); -} - -EventListener* DOMWindow::oncanplay() const -{ - return getAttributeEventListener(eventNames().canplayEvent); -} - -void DOMWindow::setOncanplay(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().canplayEvent, eventListener); -} - -EventListener* DOMWindow::oncanplaythrough() const -{ - return getAttributeEventListener(eventNames().canplaythroughEvent); -} - -void DOMWindow::setOncanplaythrough(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().canplaythroughEvent, eventListener); -} - -EventListener* DOMWindow::ondurationchange() const -{ - return getAttributeEventListener(eventNames().durationchangeEvent); -} - -void DOMWindow::setOndurationchange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().durationchangeEvent, eventListener); -} - -EventListener* DOMWindow::onemptied() const -{ - return getAttributeEventListener(eventNames().emptiedEvent); -} - -void DOMWindow::setOnemptied(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().emptiedEvent, eventListener); -} - -EventListener* DOMWindow::onended() const -{ - return getAttributeEventListener(eventNames().endedEvent); -} - -void DOMWindow::setOnended(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().endedEvent, eventListener); -} - -EventListener* DOMWindow::onloadeddata() const -{ - return getAttributeEventListener(eventNames().loadeddataEvent); -} - -void DOMWindow::setOnloadeddata(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadeddataEvent, eventListener); -} - -EventListener* DOMWindow::onloadedmetadata() const -{ - return getAttributeEventListener(eventNames().loadedmetadataEvent); -} - -void DOMWindow::setOnloadedmetadata(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadedmetadataEvent, eventListener); -} - -EventListener* DOMWindow::onpause() const -{ - return getAttributeEventListener(eventNames().pauseEvent); -} - -void DOMWindow::setOnpause(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().pauseEvent, eventListener); -} - -EventListener* DOMWindow::onplay() const -{ - return getAttributeEventListener(eventNames().playEvent); -} - -void DOMWindow::setOnplay(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().playEvent, eventListener); -} - -EventListener* DOMWindow::onplaying() const -{ - return getAttributeEventListener(eventNames().playingEvent); -} - -void DOMWindow::setOnplaying(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().playingEvent, eventListener); -} - -EventListener* DOMWindow::onratechange() const -{ - return getAttributeEventListener(eventNames().ratechangeEvent); -} - -void DOMWindow::setOnratechange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().ratechangeEvent, eventListener); -} - -EventListener* DOMWindow::onseeked() const -{ - return getAttributeEventListener(eventNames().seekedEvent); -} - -void DOMWindow::setOnseeked(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().seekedEvent, eventListener); -} - -EventListener* DOMWindow::onseeking() const -{ - return getAttributeEventListener(eventNames().seekingEvent); -} - -void DOMWindow::setOnseeking(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().seekingEvent, eventListener); -} - -EventListener* DOMWindow::ontimeupdate() const -{ - return getAttributeEventListener(eventNames().timeupdateEvent); -} - -void DOMWindow::setOntimeupdate(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().timeupdateEvent, eventListener); -} - -EventListener* DOMWindow::onvolumechange() const -{ - return getAttributeEventListener(eventNames().volumechangeEvent); -} - -void DOMWindow::setOnvolumechange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().volumechangeEvent, eventListener); -} - -EventListener* DOMWindow::onwaiting() const -{ - return getAttributeEventListener(eventNames().waitingEvent); -} - -void DOMWindow::setOnwaiting(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().waitingEvent, eventListener); -} - -EventListener* DOMWindow::onloadstart() const -{ - return getAttributeEventListener(eventNames().loadstartEvent); -} - -void DOMWindow::setOnloadstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadstartEvent, eventListener); -} - -EventListener* DOMWindow::onprogress() const -{ - return getAttributeEventListener(eventNames().progressEvent); -} - -void DOMWindow::setOnprogress(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().progressEvent, eventListener); -} - -EventListener* DOMWindow::onstalled() const -{ - return getAttributeEventListener(eventNames().stalledEvent); -} - -void DOMWindow::setOnstalled(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().stalledEvent, eventListener); -} - -EventListener* DOMWindow::onsuspend() const -{ - return getAttributeEventListener(eventNames().suspendEvent); -} - -void DOMWindow::setOnsuspend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().suspendEvent, eventListener); -} - -EventListener* DOMWindow::oninput() const -{ - return getAttributeEventListener(eventNames().inputEvent); -} - -void DOMWindow::setOninput(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().inputEvent, eventListener); -} - -EventListener* DOMWindow::onmessage() const -{ - return getAttributeEventListener(eventNames().messageEvent); -} - -void DOMWindow::setOnmessage(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().messageEvent, eventListener); -} - -EventListener* DOMWindow::oncontextmenu() const -{ - return getAttributeEventListener(eventNames().contextmenuEvent); -} - -void DOMWindow::setOncontextmenu(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().contextmenuEvent, eventListener); -} - -EventListener* DOMWindow::oninvalid() const +void DOMWindow::captureEvents() { - return getAttributeEventListener(eventNames().invalidEvent); + // Not implemented. } -void DOMWindow::setOninvalid(PassRefPtr<EventListener> eventListener) +void DOMWindow::releaseEvents() { - setAttributeEventListener(eventNames().invalidEvent, eventListener); + // Not implemented. } -void DOMWindow::captureEvents() +EventTargetData* DOMWindow::eventTargetData() { - // Not implemented. + return &m_eventTargetData; } -void DOMWindow::releaseEvents() +EventTargetData* DOMWindow::ensureEventTargetData() { - // Not implemented. + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h index db4edda..f2177ee 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h @@ -85,6 +85,13 @@ namespace WebCore { void clear(); +#if ENABLE(ORIENTATION_EVENTS) + // This is the interface orientation in degrees. Some examples are: + // 0 is straight up; -90 is when the device is rotated 90 clockwise; + // 90 is when rotated counter clockwise. + int orientation() const; +#endif + void setSecurityOrigin(SecurityOrigin* securityOrigin) { m_securityOrigin = securityOrigin; } SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } @@ -230,159 +237,84 @@ namespace WebCore { // Events // EventTarget API - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual void removeAllEventListeners(); - void handleEvent(Event*, bool useCapture, RegisteredEventListenerVector* = 0); - - void dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable); + using EventTarget::dispatchEvent; + bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget); void dispatchLoadEvent(); - void dispatchUnloadEvent(RegisteredEventListenerVector* = 0); - PassRefPtr<BeforeUnloadEvent> dispatchBeforeUnloadEvent(RegisteredEventListenerVector* = 0); - void dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted); - - // Used for legacy "onEvent" property APIs. - void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); - void clearAttributeEventListener(const AtomicString& eventType); - EventListener* getAttributeEventListener(const AtomicString& eventType) const; - - const RegisteredEventListenerVector& eventListeners() const { return m_eventListeners; } - bool hasEventListener(const AtomicString& eventType); - void removeAllEventListeners(); - - EventListener* onabort() const; - void setOnabort(PassRefPtr<EventListener>); - EventListener* onblur() const; - void setOnblur(PassRefPtr<EventListener>); - EventListener* onchange() const; - void setOnchange(PassRefPtr<EventListener>); - EventListener* onclick() const; - void setOnclick(PassRefPtr<EventListener>); - EventListener* ondblclick() const; - void setOndblclick(PassRefPtr<EventListener>); - EventListener* ondrag() const; - void setOndrag(PassRefPtr<EventListener>); - EventListener* ondragend() const; - void setOndragend(PassRefPtr<EventListener>); - EventListener* ondragenter() const; - void setOndragenter(PassRefPtr<EventListener>); - EventListener* ondragleave() const; - void setOndragleave(PassRefPtr<EventListener>); - EventListener* ondragover() const; - void setOndragover(PassRefPtr<EventListener>); - EventListener* ondragstart() const; - void setOndragstart(PassRefPtr<EventListener>); - EventListener* ondrop() const; - void setOndrop(PassRefPtr<EventListener>); - EventListener* onerror() const; - void setOnerror(PassRefPtr<EventListener>); - EventListener* onfocus() const; - void setOnfocus(PassRefPtr<EventListener>); - EventListener* onhashchange() const; - void setOnhashchange(PassRefPtr<EventListener>); - EventListener* onkeydown() const; - void setOnkeydown(PassRefPtr<EventListener>); - EventListener* onkeypress() const; - void setOnkeypress(PassRefPtr<EventListener>); - EventListener* onkeyup() const; - void setOnkeyup(PassRefPtr<EventListener>); - EventListener* onload() const; - void setOnload(PassRefPtr<EventListener>); - EventListener* onmousedown() const; - void setOnmousedown(PassRefPtr<EventListener>); - EventListener* onmousemove() const; - void setOnmousemove(PassRefPtr<EventListener>); - EventListener* onmouseout() const; - void setOnmouseout(PassRefPtr<EventListener>); - EventListener* onmouseover() const; - void setOnmouseover(PassRefPtr<EventListener>); - EventListener* onmouseup() const; - void setOnmouseup(PassRefPtr<EventListener>); - EventListener* onmousewheel() const; - void setOnmousewheel(PassRefPtr<EventListener>); - EventListener* onoffline() const; - void setOnoffline(PassRefPtr<EventListener>); - EventListener* ononline() const; - void setOnonline(PassRefPtr<EventListener>); - EventListener* onpagehide() const; - void setOnpagehide(PassRefPtr<EventListener>); - EventListener* onpageshow() const; - void setOnpageshow(PassRefPtr<EventListener>); - EventListener* onreset() const; - void setOnreset(PassRefPtr<EventListener>); - EventListener* onresize() const; - void setOnresize(PassRefPtr<EventListener>); - EventListener* onscroll() const; - void setOnscroll(PassRefPtr<EventListener>); - EventListener* onsearch() const; - void setOnsearch(PassRefPtr<EventListener>); - EventListener* onselect() const; - void setOnselect(PassRefPtr<EventListener>); - EventListener* onstorage() const; - void setOnstorage(PassRefPtr<EventListener>); - EventListener* onsubmit() const; - void setOnsubmit(PassRefPtr<EventListener>); - EventListener* onunload() const; - void setOnunload(PassRefPtr<EventListener>); - EventListener* onbeforeunload() const; - void setOnbeforeunload(PassRefPtr<EventListener>); - EventListener* onwebkitanimationstart() const; - void setOnwebkitanimationstart(PassRefPtr<EventListener>); - EventListener* onwebkitanimationiteration() const; - void setOnwebkitanimationiteration(PassRefPtr<EventListener>); - EventListener* onwebkitanimationend() const; - void setOnwebkitanimationend(PassRefPtr<EventListener>); - EventListener* onwebkittransitionend() const; - void setOnwebkittransitionend(PassRefPtr<EventListener>); - EventListener* oncanplay() const; - void setOncanplay(PassRefPtr<EventListener>); - EventListener* oncanplaythrough() const; - void setOncanplaythrough(PassRefPtr<EventListener>); - EventListener* ondurationchange() const; - void setOndurationchange(PassRefPtr<EventListener>); - EventListener* onemptied() const; - void setOnemptied(PassRefPtr<EventListener>); - EventListener* onended() const; - void setOnended(PassRefPtr<EventListener>); - EventListener* onloadeddata() const; - void setOnloadeddata(PassRefPtr<EventListener>); - EventListener* onloadedmetadata() const; - void setOnloadedmetadata(PassRefPtr<EventListener>); - EventListener* onpause() const; - void setOnpause(PassRefPtr<EventListener>); - EventListener* onplay() const; - void setOnplay(PassRefPtr<EventListener>); - EventListener* onplaying() const; - void setOnplaying(PassRefPtr<EventListener>); - EventListener* onratechange() const; - void setOnratechange(PassRefPtr<EventListener>); - EventListener* onseeked() const; - void setOnseeked(PassRefPtr<EventListener>); - EventListener* onseeking() const; - void setOnseeking(PassRefPtr<EventListener>); - EventListener* ontimeupdate() const; - void setOntimeupdate(PassRefPtr<EventListener>); - EventListener* onvolumechange() const; - void setOnvolumechange(PassRefPtr<EventListener>); - EventListener* onwaiting() const; - void setOnwaiting(PassRefPtr<EventListener>); - EventListener* onloadstart() const; - void setOnloadstart(PassRefPtr<EventListener>); - EventListener* onprogress() const; - void setOnprogress(PassRefPtr<EventListener>); - EventListener* onstalled() const; - void setOnstalled(PassRefPtr<EventListener>); - EventListener* onsuspend() const; - void setOnsuspend(PassRefPtr<EventListener>); - EventListener* oninput() const; - void setOninput(PassRefPtr<EventListener>); - EventListener* onmessage() const; - void setOnmessage(PassRefPtr<EventListener>); - EventListener* oncontextmenu() const; - void setOncontextmenu(PassRefPtr<EventListener>); - EventListener* oninvalid() const; - void setOninvalid(PassRefPtr<EventListener>); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(offline); + DEFINE_ATTRIBUTE_EVENT_LISTENER(online); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(resize); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(storage); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + DEFINE_ATTRIBUTE_EVENT_LISTENER(unload); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload); + DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay); + DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough); + DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied); + DEFINE_ATTRIBUTE_EVENT_LISTENER(ended); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pause); + DEFINE_ATTRIBUTE_EVENT_LISTENER(play); + DEFINE_ATTRIBUTE_EVENT_LISTENER(playing); + DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked); + DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking); + DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled); + DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); +#if ENABLE(ORIENTATION_EVENTS) + DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange); +#endif + + DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart); + DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration); + DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd); + DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd); void captureEvents(); void releaseEvents(); @@ -417,8 +349,8 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } - - void dispatchEventWithDocumentAsTarget(PassRefPtr<Event>, RegisteredEventListenerVector* = 0); + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); RefPtr<SecurityOrigin> m_securityOrigin; KURL m_url; @@ -447,7 +379,7 @@ namespace WebCore { mutable RefPtr<NotificationCenter> m_notifications; #endif - RegisteredEventListenerVector m_eventListeners; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl index dcd83d9..f36175e 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl @@ -39,6 +39,7 @@ module window { CustomNativeConverter, CustomPutFunction, ExtendsDOMGlobalObject, + EventTarget, GenerateNativeConverter, LegacyParent=JSDOMWindowBase ] DOMWindow { @@ -170,6 +171,13 @@ module window { readonly attribute NotificationCenter webkitNotifications; #endif +#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS + // This is the interface orientation in degrees. Some examples are: + // 0 is straight up; -90 is when the device is rotated 90 clockwise; + // 90 is when rotated counter clockwise. + readonly attribute long orientation; +#endif + attribute [Replaceable] Console console; // cross-document messaging @@ -265,7 +273,6 @@ module window { // attribute EventListener onbeforeprint; // attribute EventListener onformchange; // attribute EventListener onforminput; - // attribute EventListener onhashchange; // attribute EventListener onpopstate; // attribute EventListener onreadystatechange; // attribute EventListener onredo; @@ -279,6 +286,9 @@ module window { attribute EventListener onwebkitanimationiteration; attribute EventListener onwebkitanimationstart; attribute EventListener onwebkittransitionend; +#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS + attribute EventListener onorientationchange; +#endif // EventTarget interface [Custom] void addEventListener(in DOMString type, diff --git a/src/3rdparty/webkit/WebCore/page/DragController.cpp b/src/3rdparty/webkit/WebCore/page/DragController.cpp index 676c6d9..ab3a653 100644 --- a/src/3rdparty/webkit/WebCore/page/DragController.cpp +++ b/src/3rdparty/webkit/WebCore/page/DragController.cpp @@ -47,6 +47,7 @@ #include "HTMLAnchorElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" +#include "HitTestRequest.h" #include "HitTestResult.h" #include "Image.h" #include "MoveSelectionCommand.h" @@ -54,6 +55,7 @@ #include "Page.h" #include "RenderFileUploadControl.h" #include "RenderImage.h" +#include "RenderView.h" #include "ReplaceSelectionCommand.h" #include "ResourceRequest.h" #include "SelectionController.h" @@ -254,6 +256,25 @@ static HTMLInputElement* asFileInput(Node* node) return 0; } +static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p) +{ + float zoomFactor = documentUnderMouse->frame()->pageZoomFactor(); + IntPoint point = roundedIntPoint(FloatPoint(p.x() * zoomFactor, p.y() * zoomFactor)); + + HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); + HitTestResult result(point); + documentUnderMouse->renderView()->layer()->hitTest(request, result); + + Node* n = result.innerNode(); + while (n && !n->isElementNode()) + n = n->parentNode(); + if (n) + n = n->shadowAncestorNode(); + + ASSERT(n); + return static_cast<Element*>(n); +} + bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragOperation& operation) { ASSERT(dragData); @@ -288,10 +309,8 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a return true; } - IntPoint dragPos = dragData->clientPosition(); - IntPoint point = frameView->windowToContents(dragPos); - Element* element = m_documentUnderMouse->elementFromPoint(point.x(), point.y()); - ASSERT(element); + IntPoint point = frameView->windowToContents(dragData->clientPosition()); + Element* element = elementUnderMouse(m_documentUnderMouse, point); if (!asFileInput(element)) { VisibleSelection dragCaret = m_documentUnderMouse->frame()->visiblePositionForPoint(point); m_page->dragCaretController()->setSelection(dragCaret); @@ -341,8 +360,7 @@ bool DragController::concludeEditDrag(DragData* dragData) return false; IntPoint point = m_documentUnderMouse->view()->windowToContents(dragData->clientPosition()); - Element* element = m_documentUnderMouse->elementFromPoint(point.x(), point.y()); - ASSERT(element); + Element* element = elementUnderMouse(m_documentUnderMouse, point); Frame* innerFrame = element->ownerDocument()->frame(); ASSERT(innerFrame); diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp index abe40c7..8d519ef 100644 --- a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp +++ b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp @@ -101,7 +101,7 @@ const double autoscrollInterval = 0.05; static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&); -static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node) +static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode) { if (!delta) return; @@ -110,12 +110,13 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir RenderBox* enclosingBox = node->renderer()->enclosingBox(); if (e.granularity() == ScrollByPageWheelEvent) { - if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1)) + if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode)) e.accept(); return; - } + } + float pixelsToScroll = delta > 0 ? delta : -delta; - if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll)) + if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode)) e.accept(); } @@ -205,6 +206,7 @@ void EventHandler::clear() m_capturesDragging = false; m_capturingMouseEventsNode = 0; m_latchedWheelEventNode = 0; + m_previousWheelScrolledNode = 0; } void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result) @@ -1774,7 +1776,7 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) Node* node; bool isOverWidget; bool didSetLatchedNode = false; - + if (m_useLatchedWheelEventNode) { if (!m_latchedWheelEventNode) { HitTestRequest request(HitTestRequest::ReadOnly); @@ -1784,20 +1786,22 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) m_widgetIsLatched = result.isOverWidget(); didSetLatchedNode = true; } - + node = m_latchedWheelEventNode.get(); isOverWidget = m_widgetIsLatched; } else { if (m_latchedWheelEventNode) m_latchedWheelEventNode = 0; - + if (m_previousWheelScrolledNode) + m_previousWheelScrolledNode = 0; + HitTestRequest request(HitTestRequest::ReadOnly); HitTestResult result(vPoint); doc->renderView()->layer()->hitTest(request, result); node = result.innerNode(); isOverWidget = result.isOverWidget(); } - + if (node) { // Figure out which view to send the event to. RenderObject* target = node->renderer(); @@ -1814,17 +1818,20 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) node->dispatchWheelEvent(e); if (e.isAccepted()) return true; - + // If we don't have a renderer, send the wheel event to the first node we find with a renderer. // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll. while (node && !node->renderer()) node = node->parent(); - + if (node && node->renderer()) { // Just break up into two scrolls if we need to. Diagonal movement on // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set). - scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node); - scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node); + Node* stopNode = m_previousWheelScrolledNode.get(); + scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node, &stopNode); + scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node, &stopNode); + if (!m_useLatchedWheelEventNode) + m_previousWheelScrolledNode = stopNode; } } @@ -1890,7 +1897,7 @@ bool EventHandler::canMouseDownStartSelect(Node* node) for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) { if (Node* node = curr->node()) - return node->dispatchEvent(eventNames().selectstartEvent, true, true); + return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true)); } return true; @@ -1904,7 +1911,7 @@ bool EventHandler::canMouseDragExtendSelect(Node* node) for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) { if (Node* node = curr->node()) - return node->dispatchEvent(eventNames().selectstartEvent, true, true); + return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true)); } return true; @@ -2459,7 +2466,7 @@ void EventHandler::capsLockStateMayHaveChanged() void EventHandler::sendResizeEvent() { - m_frame->document()->dispatchWindowEvent(eventNames().resizeEvent, false, false); + m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false)); } void EventHandler::sendScrollEvent() @@ -2468,7 +2475,7 @@ void EventHandler::sendScrollEvent() if (!v) return; v->setWasScrolledByUser(true); - m_frame->document()->dispatchEvent(eventNames().scrollEvent, true, false); + m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false)); } bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar) diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.h b/src/3rdparty/webkit/WebCore/page/EventHandler.h index b390457..7066252 100644 --- a/src/3rdparty/webkit/WebCore/page/EventHandler.h +++ b/src/3rdparty/webkit/WebCore/page/EventHandler.h @@ -378,7 +378,9 @@ private: bool m_useLatchedWheelEventNode; RefPtr<Node> m_latchedWheelEventNode; bool m_widgetIsLatched; - + + RefPtr<Node> m_previousWheelScrolledNode; + #if PLATFORM(MAC) NSView *m_mouseDownView; bool m_sendingEventToSubview; diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.cpp b/src/3rdparty/webkit/WebCore/page/EventSource.cpp index afec20f..ae3c0c3 100644 --- a/src/3rdparty/webkit/WebCore/page/EventSource.cpp +++ b/src/3rdparty/webkit/WebCore/page/EventSource.cpp @@ -108,7 +108,7 @@ void EventSource::endRequest() m_requestInFlight = false; if (!m_failSilently) - dispatchGenericEvent(eventNames().errorEvent); + dispatchEvent(Event::create(eventNames().errorEvent, false, false)); if (!scriptExecutionContext()->isWorkerContext()) cache()->loader()->nonCacheRequestComplete(m_url); @@ -162,70 +162,12 @@ ScriptExecutionContext* EventSource::scriptExecutionContext() const return ActiveDOMObject::scriptExecutionContext(); } -void EventSource::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void EventSource::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool EventSource::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - EventListener* attributeListener = m_attributeListeners.get(event->type()).get(); - if (attributeListener) { - event->setTarget(this); - event->setCurrentTarget(this); - attributeListener->handleEvent(event.get(), false); - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - void EventSource::didReceiveResponse(const ResourceResponse& response) { int statusCode = response.httpStatusCode(); if (statusCode == 200 && response.httpHeaderField("Content-Type") == "text/event-stream") { m_state = OPEN; - dispatchGenericEvent(eventNames().openEvent); + dispatchEvent(Event::create(eventNames().openEvent, false, false)); } else { if (statusCode <= 200 || statusCode > 299) m_state = CLOSED; @@ -304,7 +246,7 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int { if (!lineLength) { if (!m_data.isEmpty()) - dispatchMessageEvent(); + dispatchEvent(createMessageEvent()); if (!m_eventName.isEmpty()) m_eventName = ""; } else if (fieldLength) { @@ -344,27 +286,26 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int } } -void EventSource::dispatchGenericEvent(const AtomicString& type) +void EventSource::stop() { - RefPtr<Event> evt = Event::create(type, false, false); - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); + close(); } -void EventSource::dispatchMessageEvent() +PassRefPtr<MessageEvent> EventSource::createMessageEvent() { - RefPtr<MessageEvent> evt = MessageEvent::create(); - String eventName = m_eventName.isEmpty() ? eventNames().messageEvent.string() : m_eventName; - evt->initMessageEvent(eventName, false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0); - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); + RefPtr<MessageEvent> event = MessageEvent::create(); + event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0); + return event.release(); } -void EventSource::stop() +EventTargetData* EventSource::eventTargetData() { - close(); + return &m_eventTargetData; +} + +EventTargetData* EventSource::ensureEventTargetData() +{ + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.h b/src/3rdparty/webkit/WebCore/page/EventSource.h index df55694..5b037a4 100644 --- a/src/3rdparty/webkit/WebCore/page/EventSource.h +++ b/src/3rdparty/webkit/WebCore/page/EventSource.h @@ -50,6 +50,7 @@ namespace WebCore { + class MessageEvent; class ResourceResponse; class TextResourceDecoder; class ThreadableLoader; @@ -71,14 +72,9 @@ namespace WebCore { State readyState() const; - void setOnopen(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().openEvent, eventListener); } - EventListener* onopen() const { return m_attributeListeners.get(eventNames().openEvent).get(); } - - void setOnmessage(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().messageEvent, eventListener); } - EventListener* onmessage() const { return m_attributeListeners.get(eventNames().messageEvent).get(); } - - void setOnerror(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().errorEvent, eventListener); } - EventListener* onerror() const { return m_attributeListeners.get(eventNames().errorEvent).get(); } + DEFINE_ATTRIBUTE_EVENT_LISTENER(open); + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); void close(); @@ -88,14 +84,6 @@ namespace WebCore { virtual EventSource* toEventSource() { return this; } virtual ScriptExecutionContext* scriptExecutionContext() const; - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - EventListenersMap& eventListeners() { return m_eventListeners; } - virtual void stop(); private: @@ -103,6 +91,8 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); virtual void didReceiveResponse(const ResourceResponse& response); virtual void didReceiveData(const char* data, int length); @@ -116,15 +106,11 @@ namespace WebCore { void reconnectTimerFired(Timer<EventSource>*); void parseEventStream(); void parseEventStreamLine(unsigned int pos, int fieldLength, int lineLength); - void dispatchGenericEvent(const AtomicString& type); - void dispatchMessageEvent(); + PassRefPtr<MessageEvent> createMessageEvent(); KURL m_url; State m_state; - HashMap<AtomicString, RefPtr<EventListener> > m_attributeListeners; - EventListenersMap m_eventListeners; - RefPtr<TextResourceDecoder> m_decoder; RefPtr<ThreadableLoader> m_loader; Timer<EventSource> m_reconnectTimer; @@ -137,6 +123,8 @@ namespace WebCore { String m_lastEventId; unsigned long long m_reconnectDelay; String m_origin; + + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.idl b/src/3rdparty/webkit/WebCore/page/EventSource.idl index c438e682..561bd68 100644 --- a/src/3rdparty/webkit/WebCore/page/EventSource.idl +++ b/src/3rdparty/webkit/WebCore/page/EventSource.idl @@ -33,7 +33,7 @@ module window { interface [ Conditional=EVENTSOURCE, - CustomMarkFunction, + EventTarget, NoStaticTables ] EventSource { diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.cpp b/src/3rdparty/webkit/WebCore/page/FocusController.cpp index bc9e477..5e78c7d 100644 --- a/src/3rdparty/webkit/WebCore/page/FocusController.cpp +++ b/src/3rdparty/webkit/WebCore/page/FocusController.cpp @@ -36,6 +36,7 @@ #include "Event.h" #include "EventHandler.h" #include "EventNames.h" +#include "ExceptionCode.h" #include "Frame.h" #include "FrameView.h" #include "FrameTree.h" @@ -62,7 +63,7 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool // https://bugs.webkit.org/show_bug.cgi?id=27105 if (!focused && document->focusedNode()) document->focusedNode()->dispatchBlurEvent(); - document->dispatchWindowEvent(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false); + document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false)); if (focused && document->focusedNode()) document->focusedNode()->dispatchFocusEvent(); } @@ -87,12 +88,12 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame) // Now that the frame is updated, fire events and update the selection focused states of both frames. if (oldFrame && oldFrame->view()) { oldFrame->selection()->setFocused(false); - oldFrame->document()->dispatchWindowEvent(eventNames().blurEvent, false, false); + oldFrame->document()->dispatchWindowEvent(Event::create(eventNames().blurEvent, false, false)); } if (newFrame && newFrame->view() && isFocused()) { newFrame->selection()->setFocused(true); - newFrame->document()->dispatchWindowEvent(eventNames().focusEvent, false, false); + newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false)); } } diff --git a/src/3rdparty/webkit/WebCore/page/Frame.cpp b/src/3rdparty/webkit/WebCore/page/Frame.cpp index 7a3ed27..28e6a9e 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.cpp +++ b/src/3rdparty/webkit/WebCore/page/Frame.cpp @@ -97,6 +97,10 @@ #include "WMLNames.h" #endif +#if ENABLE(MATHML) +#include "MathMLNames.h" +#endif + using namespace std; namespace WebCore { @@ -127,6 +131,9 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* , m_eventHandler(this) , m_animationController(this) , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired) +#if ENABLE(ORIENTATION_EVENTS) + , m_orientation(0) +#endif , m_caretVisible(false) , m_caretPaint(true) , m_highlightTextMatches(false) @@ -152,6 +159,10 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* WMLNames::init(); #endif +#if ENABLE(MATHML) + MathMLNames::init(); +#endif + XMLNames::init(); if (!ownerElement) @@ -268,6 +279,15 @@ void Frame::setDocument(PassRefPtr<Document> newDoc) m_script.updateDocument(); } +#if ENABLE(ORIENTATION_EVENTS) +void Frame::sendOrientationChangeEvent(int orientation) +{ + m_orientation = orientation; + if (Document* doc = document()) + doc->dispatchWindowEvent(eventNames().orientationchangeEvent, false, false); +} +#endif // ENABLE(ORIENTATION_EVENTS) + Settings* Frame::settings() const { return m_page ? m_page->settings() : 0; @@ -1645,7 +1665,7 @@ void Frame::unfocusWindow() page()->chrome()->unfocus(); } -bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) +bool Frame::shouldClose() { Chrome* chrome = page() ? page()->chrome() : 0; if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel()) @@ -1659,7 +1679,8 @@ bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) if (!body) return true; - RefPtr<BeforeUnloadEvent> beforeUnloadEvent = m_domWindow->dispatchBeforeUnloadEvent(alternateEventListeners); + RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create(); + m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document()); if (!beforeUnloadEvent->defaultPrevented()) doc->defaultEventHandler(beforeUnloadEvent.get()); diff --git a/src/3rdparty/webkit/WebCore/page/Frame.h b/src/3rdparty/webkit/WebCore/page/Frame.h index ef803f1..b98dbc4 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.h +++ b/src/3rdparty/webkit/WebCore/page/Frame.h @@ -153,6 +153,14 @@ namespace WebCore { void setDocument(PassRefPtr<Document>); +#if ENABLE(ORIENTATION_EVENTS) + // Orientation is the interface orientation in degrees. Some examples are: + // 0 is straight up; -90 is when the device is rotated 90 clockwise; + // 90 is when rotated counter clockwise. + void sendOrientationChangeEvent(int orientation); + int orientation() const { return m_orientation; } +#endif + void clearTimers(); static void clearTimers(FrameView*, Document*); @@ -190,7 +198,7 @@ namespace WebCore { public: void focusWindow(); void unfocusWindow(); - bool shouldClose(RegisteredEventListenerVector* alternateEventListeners = 0); + bool shouldClose(); void scheduleClose(); void setJSStatusBarText(const String&); @@ -354,6 +362,10 @@ namespace WebCore { Timer<Frame> m_lifeSupportTimer; +#if ENABLE(ORIENTATION_EVENTS) + int m_orientation; +#endif + bool m_caretVisible; bool m_caretPaint; diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index b358018..675cba1 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -803,6 +803,22 @@ void FrameView::setScrollPosition(const IntPoint& scrollPoint) m_inProgrammaticScroll = wasInProgrammaticScroll; } +void FrameView::scrollPositionChanged() +{ + frame()->eventHandler()->sendScrollEvent(); + +#if USE(ACCELERATED_COMPOSITING) + // We need to update layer positions after scrolling to account for position:fixed layers. + Document* document = m_frame->document(); + if (!document) + return; + + RenderLayer* layer = document->renderer() ? document->renderer()->enclosingLayer() : 0; + if (layer) + layer->updateLayerPositions(RenderLayer::UpdateCompositingLayers); +#endif +} + HostWindow* FrameView::hostWindow() const { Page* page = frame() ? frame()->page() : 0; @@ -971,7 +987,8 @@ void FrameView::layoutTimerFired(Timer<FrameView>*) void FrameView::scheduleRelayout() { - ASSERT(!m_frame->document()->inPageCache()); + // FIXME: We should assert the page is not in the page cache, but that is causing + // too many false assertions. See <rdar://problem/7218118>. ASSERT(m_frame->view() == this); if (m_layoutRoot) { diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h index 617a8e9..4c900ae 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.h +++ b/src/3rdparty/webkit/WebCore/page/FrameView.h @@ -131,6 +131,7 @@ public: virtual void scrollRectIntoViewRecursively(const IntRect&); virtual void setScrollPosition(const IntPoint&); + void scrollPositionChanged(); String mediaType() const; void setMediaType(const String&); diff --git a/src/3rdparty/webkit/WebCore/page/Page.cpp b/src/3rdparty/webkit/WebCore/page/Page.cpp index f6f6a81..182d22c 100644 --- a/src/3rdparty/webkit/WebCore/page/Page.cpp +++ b/src/3rdparty/webkit/WebCore/page/Page.cpp @@ -29,8 +29,10 @@ #include "ContextMenuController.h" #include "DOMWindow.h" #include "DragController.h" +#include "ExceptionCode.h" #include "EditorClient.h" #include "EventNames.h" +#include "Event.h" #include "FileSystem.h" #include "FocusController.h" #include "Frame.h" @@ -94,7 +96,7 @@ static void networkStateChanged() AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent; for (unsigned i = 0; i < frames.size(); i++) - frames[i]->document()->dispatchWindowEvent(eventName, false, false); + frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false)); } Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient) diff --git a/src/3rdparty/webkit/WebCore/page/PageGroupLoadDeferrer.cpp b/src/3rdparty/webkit/WebCore/page/PageGroupLoadDeferrer.cpp index f274de3..122658b 100644 --- a/src/3rdparty/webkit/WebCore/page/PageGroupLoadDeferrer.cpp +++ b/src/3rdparty/webkit/WebCore/page/PageGroupLoadDeferrer.cpp @@ -41,10 +41,10 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf) if (!otherPage->defersLoading()) m_deferredFrames.append(otherPage->mainFrame()); -#if !PLATFORM(MAC) + // This code is not logically part of load deferring, but we do not want JS code executed beneath modal + // windows or sheets, which is exactly when PageGroupLoadDeferrer is used. for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) frame->document()->suspendActiveDOMObjects(); -#endif } } @@ -60,10 +60,8 @@ PageGroupLoadDeferrer::~PageGroupLoadDeferrer() if (Page* page = m_deferredFrames[i]->page()) { page->setDefersLoading(false); -#if !PLATFORM(MAC) for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) frame->document()->resumeActiveDOMObjects(); -#endif } } } diff --git a/src/3rdparty/webkit/WebCore/page/PositionOptions.h b/src/3rdparty/webkit/WebCore/page/PositionOptions.h index ed7074b..5cb66f7 100644 --- a/src/3rdparty/webkit/WebCore/page/PositionOptions.h +++ b/src/3rdparty/webkit/WebCore/page/PositionOptions.h @@ -49,10 +49,17 @@ public: m_hasTimeout = true; m_timeout = timeout; } - int maximumAge() const { return m_maximumAge; } + bool hasMaximumAge() const { return m_hasMaximumAge; } + int maximumAge() const + { + ASSERT(hasMaximumAge()); + return m_maximumAge; + } + void clearMaximumAge() { m_hasMaximumAge = false; } void setMaximumAge(int age) { ASSERT(age >= 0); + m_hasMaximumAge = true; m_maximumAge = age; } @@ -60,13 +67,14 @@ private: PositionOptions() : m_highAccuracy(false) , m_hasTimeout(false) - , m_maximumAge(0) { + setMaximumAge(0); } bool m_highAccuracy; bool m_hasTimeout; int m_timeout; + bool m_hasMaximumAge; int m_maximumAge; }; diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp index 5076adf..b91c1f1 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp @@ -221,6 +221,22 @@ bool SecurityOrigin::canRequest(const KURL& url) const return false; } +bool SecurityOrigin::taintsCanvas(const KURL& url) const +{ + if (canRequest(url)) + return false; + + // This method exists because we treat data URLs as noAccess, contrary + // to the current (9/19/2009) draft of the HTML5 specification. We still + // want to let folks paint data URLs onto untainted canvases, so we special + // case data URLs below. If we change to match HTML5 w.r.t. data URL + // security, then we can remove this method in favor of !canRequest. + if (url.protocolIs("data")) + return false; + + return true; +} + void SecurityOrigin::grantLoadLocalResources() { // This method exists only to support backwards compatibility with older diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h index c8086ac..732afa8 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h @@ -76,6 +76,11 @@ namespace WebCore { // XMLHttpRequests. bool canRequest(const KURL&) const; + // Returns true if drawing an image from this URL taints a canvas from + // this security origin. For example, call this function before + // drawing an image onto an HTML canvas element with the drawImage API. + bool taintsCanvas(const KURL&) const; + // Returns true if this SecurityOrigin can load local resources, such // as images, iframes, and style sheets, and can link to local URLs. // For example, call this function before creating an iframe to a diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp index df627d3..4fcc53c 100644 --- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp @@ -48,12 +48,14 @@ namespace WebCore { static bool isNonCanonicalCharacter(UChar c) { + // We remove all non-ASCII characters, including non-printable ASCII characters. + // // Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character. // Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the // adverse effect that we remove any legitimate zeros from a string. // // For instance: new String("http://localhost:8000") => new String("http://localhost:8"). - return (c == '\\' || c == '0' || c < ' ' || c == 127); + return (c == '\\' || c == '0' || c < ' ' || c >= 127); } String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities) diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp index 1d2ebe2..691932e 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp @@ -36,6 +36,8 @@ #include "EventNames.h" #include "Frame.h" #include "RenderView.h" +#include "WebKitAnimationEvent.h" +#include "WebKitTransitionEvent.h" #include <wtf/CurrentTime.h> #include <wtf/UnusedParam.h> @@ -136,9 +138,9 @@ void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<Animat Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end(); for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) { if (it->eventType == eventNames().webkitTransitionEndEvent) - it->element->dispatchWebKitTransitionEvent(it->eventType, it->name, it->elapsedTime); + it->element->dispatchEvent(WebKitTransitionEvent::create(it->eventType, it->name, it->elapsedTime)); else - it->element->dispatchWebKitAnimationEvent(it->eventType, it->name, it->elapsedTime); + it->element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime)); } m_eventsToDispatch.clear(); diff --git a/src/3rdparty/webkit/WebCore/platform/HostWindow.h b/src/3rdparty/webkit/WebCore/platform/HostWindow.h index 8c74d4f..80f6bdc 100644 --- a/src/3rdparty/webkit/WebCore/platform/HostWindow.h +++ b/src/3rdparty/webkit/WebCore/platform/HostWindow.h @@ -48,8 +48,8 @@ public: virtual IntPoint screenToWindow(const IntPoint&) const = 0; virtual IntRect windowToScreen(const IntRect&) const = 0; - // Method for retrieving the native window. - virtual PlatformWidget platformWindow() const = 0; + // Method for retrieving the native client of the page. + virtual PlatformPageClient platformPageClient() const = 0; // For scrolling a rect into view recursively. Useful in the cases where a WebView is embedded inside some containing // platform-specific ScrollView. diff --git a/src/3rdparty/webkit/WebCore/platform/StaticConstructors.h b/src/3rdparty/webkit/WebCore/platform/StaticConstructors.h index 5bc792c..f22383b 100644 --- a/src/3rdparty/webkit/WebCore/platform/StaticConstructors.h +++ b/src/3rdparty/webkit/WebCore/platform/StaticConstructors.h @@ -56,7 +56,7 @@ #if COMPILER(MSVC7) #define DEFINE_GLOBAL(type, name) \ const type name; -#elif COMPILER(WINSCW) +#elif PLATFORM(SYMBIAN) #define DEFINE_GLOBAL(type, name, arg...) \ const type name; #else @@ -70,7 +70,7 @@ #if COMPILER(MSVC7) #define DEFINE_GLOBAL(type, name) \ void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; -#elif COMPILER(WINSCW) +#elif PLATFORM(SYMBIAN) #define DEFINE_GLOBAL(type, name, arg...) \ void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; #else diff --git a/src/3rdparty/webkit/WebCore/platform/Widget.h b/src/3rdparty/webkit/WebCore/platform/Widget.h index a102b96..e2a7349 100644 --- a/src/3rdparty/webkit/WebCore/platform/Widget.h +++ b/src/3rdparty/webkit/WebCore/platform/Widget.h @@ -74,6 +74,13 @@ typedef BView* PlatformWidget; #include "PlatformWidget.h" #endif +#if PLATFORM(QT) +class QWebPageClient; +typedef QWebPageClient* PlatformPageClient; +#else +typedef PlatformWidget PlatformPageClient; +#endif + #include "IntPoint.h" #include "IntRect.h" #include "IntSize.h" diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FloatPoint.h b/src/3rdparty/webkit/WebCore/platform/graphics/FloatPoint.h index d953b3b..45a1e83 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/FloatPoint.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FloatPoint.h @@ -36,7 +36,7 @@ typedef struct CGPoint CGPoint; #endif -#if PLATFORM(MAC) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES typedef struct CGPoint NSPoint; #else @@ -84,7 +84,8 @@ public: operator CGPoint() const; #endif -#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) +#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \ + || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) FloatPoint(const NSPoint&); operator NSPoint() const; #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FloatRect.h b/src/3rdparty/webkit/WebCore/platform/graphics/FloatRect.h index c6a86bc..073f135 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/FloatRect.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FloatRect.h @@ -33,7 +33,7 @@ typedef struct CGRect CGRect; #endif -#if PLATFORM(MAC) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES typedef struct CGRect NSRect; #else @@ -127,7 +127,8 @@ public: operator CGRect() const; #endif -#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) +#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \ + || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) FloatRect(const NSRect&); operator NSRect() const; #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FloatSize.h b/src/3rdparty/webkit/WebCore/platform/graphics/FloatSize.h index 6e792b6..5a84fd1 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/FloatSize.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FloatSize.h @@ -34,7 +34,7 @@ typedef struct CGSize CGSize; #endif -#if PLATFORM(MAC) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES typedef struct CGSize NSSize; #else @@ -79,7 +79,8 @@ public: operator CGSize() const; #endif -#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) +#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \ + || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) explicit FloatSize(const NSSize &); // don't do this implicitly since it's lossy operator NSSize() const; #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FontDescription.h b/src/3rdparty/webkit/WebCore/platform/graphics/FontDescription.h index 27b3a05..a60af29 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/FontDescription.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FontDescription.h @@ -27,8 +27,8 @@ #include "FontFamily.h" #include "FontRenderingMode.h" +#include "FontSmoothingMode.h" #include "FontTraitsMask.h" -#include "RenderStyleConstants.h" namespace WebCore { @@ -86,7 +86,7 @@ public: bool useFixedDefaultSize() const { return genericFamily() == MonospaceFamily && !family().next() && family().family() == "-webkit-monospace"; } FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); } unsigned keywordSize() const { return m_keywordSize; } - FontSmoothing fontSmoothing() const { return static_cast<FontSmoothing>(m_fontSmoothing); } + FontSmoothingMode fontSmoothing() const { return static_cast<FontSmoothingMode>(m_fontSmoothing); } FontTraitsMask traitsMask() const; @@ -101,7 +101,7 @@ public: void setUsePrinterFont(bool p) { m_usePrinterFont = p; } void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; } void setKeywordSize(unsigned s) { m_keywordSize = s; } - void setFontSmoothing(FontSmoothing smoothing) { m_fontSmoothing = smoothing; } + void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; } private: FontFamily m_familyList; // The list of font families to be used. @@ -124,7 +124,7 @@ private: // then we can accurately translate across different generic families to adjust for different preference settings // (e.g., 13px monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size values for <font>). - unsigned m_fontSmoothing : 2; // FontSmoothing + unsigned m_fontSmoothing : 2; // FontSmoothingMode }; inline bool FontDescription::operator==(const FontDescription& other) const diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FontSmoothingMode.h b/src/3rdparty/webkit/WebCore/platform/graphics/FontSmoothingMode.h new file mode 100644 index 0000000..7c23394 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FontSmoothingMode.h @@ -0,0 +1,35 @@ +/* + * 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 FontSmoothingMode_h +#define FontSmoothingMode_h + +namespace WebCore { + + enum FontSmoothingMode { AutoSmoothing, NoSmoothing, Antialiased, SubpixelAntialiased }; + +} // namespace WebCore + +#endif // FontSmoothingMode_h diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/IntRect.h b/src/3rdparty/webkit/WebCore/platform/graphics/IntRect.h index 7578e6b..97b21bc 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/IntRect.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/IntRect.h @@ -33,7 +33,7 @@ typedef struct CGRect CGRect; #endif -#if PLATFORM(MAC) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES typedef struct CGRect NSRect; #else @@ -161,7 +161,8 @@ public: operator SkIRect() const; #endif -#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) +#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \ + || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) operator NSRect() const; #endif @@ -198,7 +199,8 @@ inline bool operator!=(const IntRect& a, const IntRect& b) IntRect enclosingIntRect(const CGRect&); #endif -#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) +#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \ + || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) IntRect enclosingIntRect(const NSRect&); #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp index be06c14..71c5cd4 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp @@ -38,6 +38,9 @@ #include <QUrl> #include <QEvent> +#if defined (__SYMBIAN32__) +#include <phonon/path.h> +#endif #include <audiooutput.h> #include <mediaobject.h> #include <videowidget.h> diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/DnsPrefetchHelper.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/DnsPrefetchHelper.cpp index 73da0a9..e687976 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/DnsPrefetchHelper.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/DnsPrefetchHelper.cpp @@ -17,6 +17,7 @@ Boston, MA 02110-1301, USA. */ +#include "config.h" #include "DnsPrefetchHelper.h" #include "CString.h" diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamError.h index dca3536..f9641ad 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamError.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,23 +28,23 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" +#ifndef SocketStreamError_h +#define SocketStreamError_h -#if ENABLE(SHARED_WORKERS) - -#include "JSSharedWorkerContext.h" - -using namespace JSC; +#include "SocketStreamErrorBase.h" namespace WebCore { -void JSSharedWorkerContext::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); + class SocketStreamError : public SocketStreamErrorBase { + public: + SocketStreamError() { } + explicit SocketStreamError(int errorCode) + : SocketStreamErrorBase(errorCode) + { + } - markIfNotNull(markStack, impl()->onconnect()); -} + }; -} // namespace WebCore +} // namespace WebCore -#endif // ENABLE(SHARED_WORKERS) +#endif // SocketStreamError_h diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandle.h b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandle.h new file mode 100644 index 0000000..64139e5 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandle.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SocketStreamHandle_h +#define SocketStreamHandle_h + +#include "SocketStreamHandleBase.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + + class AuthenticationChallenge; + class Credential; + class SocketStreamHandleClient; + + class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase { + public: + static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); } + + virtual ~SocketStreamHandle(); + + protected: + virtual int platformSend(const char* data, int length); + virtual void platformClose(); + + private: + SocketStreamHandle(const KURL&, SocketStreamHandleClient*); + + // No authentication for streams per se, but proxy may ask for credentials. + void didReceiveAuthenticationChallenge(const AuthenticationChallenge&); + void receivedCredential(const AuthenticationChallenge&, const Credential&); + void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&); + void receivedCancellation(const AuthenticationChallenge&); + }; + +} // namespace WebCore + +#endif // SocketStreamHandle_h diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp new file mode 100644 index 0000000..6aa33fc --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SocketStreamHandle.h" + +#include "KURL.h" +#include "Logging.h" +#include "NotImplemented.h" +#include "SocketStreamHandleClient.h" + +namespace WebCore { + +SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) + : SocketStreamHandleBase(url, client) +{ + LOG(Network, "SocketStreamHandle %p new client %p", this, m_client); + notImplemented(); +} + +SocketStreamHandle::~SocketStreamHandle() +{ + LOG(Network, "SocketStreamHandle %p delete", this); + setClient(0); + notImplemented(); +} + +int SocketStreamHandle::platformSend(const char*, int) +{ + LOG(Network, "SocketStreamHandle %p platformSend", this); + notImplemented(); + return 0; +} + +void SocketStreamHandle::platformClose() +{ + LOG(Network, "SocketStreamHandle %p platformClose", this); + notImplemented(); +} + +void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&) +{ + notImplemented(); +} + +void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&) +{ + notImplemented(); +} + +void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) +{ + notImplemented(); +} + +void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&) +{ + notImplemented(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/platform/qt/CookieJarQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/CookieJarQt.cpp index 56d3372..a27a06e 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/CookieJarQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/CookieJarQt.cpp @@ -48,6 +48,8 @@ namespace WebCore { #if QT_VERSION >= 0x040400 static QNetworkCookieJar *cookieJar(const Document *document) { + if (!document) + return 0; Frame *frame = document->frame(); if (!frame) return 0; diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PlatformScreenQt.cpp index 5dc0963..7ba8350 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PlatformScreenQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PlatformScreenQt.cpp @@ -36,42 +36,54 @@ #include "FrameView.h" #include "HostWindow.h" #include "Widget.h" +#include "QWebPageClient.h" #include <QApplication> #include <QDesktopWidget> namespace WebCore { +static int screenNumber(Widget* w) +{ + if (!w) + return 0; + + QWebPageClient* client = w->root()->hostWindow()->platformPageClient(); + return client ? client->screenNumber() : 0; +} + int screenDepth(Widget* w) { - QDesktopWidget* d = QApplication::desktop(); - QWidget *view = w ? w->root()->hostWindow()->platformWindow() : 0; - int screenNumber = view ? d->screenNumber(view) : 0; - return d->screen(screenNumber)->depth(); + return QApplication::desktop()->screen(screenNumber(w))->depth(); } int screenDepthPerComponent(Widget* w) { - QWidget *view = w ? w->root()->hostWindow()->platformWindow() : 0; - return view ? view->depth() : QApplication::desktop()->screen(0)->depth(); + if (w) { + QWebPageClient* client = w->root()->hostWindow()->platformPageClient(); + + if (client) { + QWidget* view = QWidget::find(client->winId()); + if (view) + return view->depth(); + } + } + return QApplication::desktop()->screen(0)->depth(); } bool screenIsMonochrome(Widget* w) { - QDesktopWidget* d = QApplication::desktop(); - QWidget *view = w ? w->root()->hostWindow()->platformWindow(): 0; - int screenNumber = view ? d->screenNumber(view) : 0; - return d->screen(screenNumber)->numColors() < 2; + return QApplication::desktop()->screen(screenNumber(w))->numColors() < 2; } FloatRect screenRect(Widget* w) { - QRect r = QApplication::desktop()->screenGeometry(w ? w->root()->hostWindow()->platformWindow(): 0); + QRect r = QApplication::desktop()->screenGeometry(screenNumber(w)); return FloatRect(r.x(), r.y(), r.width(), r.height()); } FloatRect screenAvailableRect(Widget* w) { - QRect r = QApplication::desktop()->availableGeometry(w ? w->root()->hostWindow()->platformWindow(): 0); + QRect r = QApplication::desktop()->availableGeometry(screenNumber(w)); return FloatRect(r.x(), r.y(), r.width(), r.height()); } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp index 11dfe41..9ce5838 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp @@ -30,6 +30,7 @@ #include "FrameView.h" #include "HostWindow.h" #include "PopupMenuClient.h" +#include "QWebPageClient.h" #include "QWebPopup.h" #include <QAction> @@ -85,13 +86,13 @@ void PopupMenu::populate(const IntRect& r) void PopupMenu::show(const IntRect& r, FrameView* v, int index) { - QWidget* window = v->hostWindow()->platformWindow(); + QWebPageClient* client = v->hostWindow()->platformPageClient(); populate(r); QRect rect = r; rect.moveTopLeft(v->contentsToWindow(r.topLeft())); rect.setHeight(m_popup->sizeHint().height()); - m_popup->setParent(window); + m_popup->setParent(QWidget::find(client->winId())); m_popup->setGeometry(rect); m_popup->setCurrentIndex(index); m_popup->exec(); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h b/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h new file mode 100644 index 0000000..1fc29a0 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 QWebPageClient_h +#define QWebPageClient_h + +#include <QRect> + +class QWebPageClient { +public: + virtual void scroll(int dx, int dy, const QRect&) = 0; + virtual void update(const QRect&) = 0; + + inline void resetCursor() + { + if (!cursor().bitmap() && cursor().shape() == m_lastCursor.shape()) + return; + updateCursor(m_lastCursor); + } + + inline void setCursor(const QCursor& cursor) + { + m_lastCursor = cursor; + if (!cursor.bitmap() && cursor.shape() == this->cursor().shape()) + return; + updateCursor(cursor); + } + + virtual int screenNumber() const = 0; + virtual WId winId() const = 0; + +protected: + virtual QCursor cursor() const = 0; + virtual void updateCursor(const QCursor& cursor) = 0; + +private: + QCursor m_lastCursor; +}; + +#endif diff --git a/src/3rdparty/webkit/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/WidgetQt.cpp index abcd584..4e82080 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/WidgetQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/WidgetQt.cpp @@ -30,6 +30,7 @@ */ #include "config.h" +#include "Widget.h" #include "Cursor.h" #include "Font.h" @@ -37,8 +38,8 @@ #include "HostWindow.h" #include "IntRect.h" #include "ScrollView.h" -#include "Widget.h" #include "NotImplemented.h" +#include "QWebPageClient.h" #include "qwebframe.h" #include "qwebframe_p.h" @@ -81,15 +82,10 @@ void Widget::setFocus() void Widget::setCursor(const Cursor& cursor) { #ifndef QT_NO_CURSOR - QWidget* widget = root()->hostWindow()->platformWindow(); - - if (!widget) - return; - - if (!cursor.impl().bitmap() && widget->cursor().shape() == cursor.impl().shape()) - return; + QWebPageClient* pageClient = root()->hostWindow()->platformPageClient(); - widget->setProperty("WebCoreCursor", cursor.impl()); + if (pageClient) + pageClient->setCursor(cursor.impl()); #endif } diff --git a/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.cpp b/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.cpp index 0a236be..a4b2ac8 100644 --- a/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.cpp +++ b/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.cpp @@ -30,9 +30,10 @@ namespace WebCore { -SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db) +SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db, bool readOnly) : m_db(db) , m_inProgress(false) + , m_readOnly(readOnly) { } @@ -46,7 +47,17 @@ void SQLiteTransaction::begin() { if (!m_inProgress) { ASSERT(!m_db.m_transactionInProgress); - m_inProgress = m_db.executeCommand("BEGIN;"); + // Call BEGIN IMMEDIATE for a write transaction to acquire + // a RESERVED lock on the DB file. Otherwise, another write + // transaction (on another connection) could make changes + // to the same DB file before this transaction gets to execute + // any statements. If that happens, this transaction will fail. + // http://www.sqlite.org/lang_transaction.html + // http://www.sqlite.org/lockingv3.html#locking + if (m_readOnly) + m_inProgress = m_db.executeCommand("BEGIN;"); + else + m_inProgress = m_db.executeCommand("BEGIN IMMEDIATE;"); m_db.m_transactionInProgress = m_inProgress; } } diff --git a/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.h b/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.h index cf5a180..557d81cb 100644 --- a/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.h +++ b/src/3rdparty/webkit/WebCore/platform/sql/SQLiteTransaction.h @@ -35,7 +35,7 @@ class SQLiteDatabase; class SQLiteTransaction : public Noncopyable { public: - SQLiteTransaction(SQLiteDatabase& db); + SQLiteTransaction(SQLiteDatabase& db, bool readOnly = false); ~SQLiteTransaction(); void begin(); @@ -47,10 +47,9 @@ public: private: SQLiteDatabase& m_db; bool m_inProgress; - + bool m_readOnly; }; } // namespace WebCore #endif // SQLiteTransation_H - diff --git a/src/3rdparty/webkit/WebCore/platform/text/PlatformString.h b/src/3rdparty/webkit/WebCore/platform/text/PlatformString.h index 258b28d..b9b4078 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/PlatformString.h +++ b/src/3rdparty/webkit/WebCore/platform/text/PlatformString.h @@ -254,6 +254,14 @@ public: // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3. WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; } + // Counts the number of grapheme clusters. A surrogate pair or a sequence + // of a non-combining character and following combining characters is + // counted as 1 grapheme cluster. + unsigned numGraphemeClusters() const; + // Returns the number of characters which will be less than or equal to + // the specified grapheme cluster length. + unsigned numCharactersInGraphemeClusters(unsigned) const; + private: RefPtr<StringImpl> m_impl; }; diff --git a/src/3rdparty/webkit/WebCore/platform/text/String.cpp b/src/3rdparty/webkit/WebCore/platform/text/String.cpp index 2730939..e892ef6 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/String.cpp +++ b/src/3rdparty/webkit/WebCore/platform/text/String.cpp @@ -25,6 +25,7 @@ #include "CString.h" #include "FloatConversion.h" #include "StringBuffer.h" +#include "TextBreakIterator.h" #include "TextEncoding.h" #include <wtf/dtoa.h> #include <limits> @@ -921,6 +922,31 @@ PassRefPtr<SharedBuffer> utf8Buffer(const String& string) return SharedBuffer::adoptVector(buffer); } +unsigned String::numGraphemeClusters() const +{ + TextBreakIterator* it = characterBreakIterator(characters(), length()); + if (!it) + return length(); + + unsigned num = 0; + while (textBreakNext(it) != TextBreakDone) + ++num; + return num; +} + +unsigned String::numCharactersInGraphemeClusters(unsigned numGraphemeClusters) const +{ + TextBreakIterator* it = characterBreakIterator(characters(), length()); + if (!it) + return min(length(), numGraphemeClusters); + + for (unsigned i = 0; i < numGraphemeClusters; ++i) { + if (textBreakNext(it) == TextBreakDone) + return length(); + } + return textBreakCurrent(it); +} + } // namespace WebCore #ifndef NDEBUG diff --git a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp index d0a3288..226aab6 100644 --- a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp @@ -75,6 +75,7 @@ using JSC::UString; #if PLATFORM(QT) #include <QWidget> #include <QKeyEvent> +#include "QWebPageClient.h" QT_BEGIN_NAMESPACE #if QT_VERSION < 0x040500 extern Q_GUI_EXPORT WindowPtr qt_mac_window_for(const QWidget* w); @@ -171,7 +172,13 @@ bool PluginView::platformStart() return false; } - setPlatformPluginWidget(m_parentFrame->view()->hostWindow()->platformWindow()); +#if PLATFORM(QT) + if (QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient()) { + if (QWidget* window = QWidget::find(client->winId())) { + setPlatformPluginWidget(window); + } + } +#endif show(); @@ -421,6 +428,14 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) setNPWindowIfNeeded(); + CGContextRef cgContext = m_npCgContext.context; + if (!cgContext) + return; + + CGContextSaveGState(cgContext); + IntPoint offset = frameRect().location(); + CGContextTranslateCTM(cgContext, offset.x(), offset.y()); + EventRecord event; event.what = updateEvt; event.message = (long unsigned int)m_npCgContext.window; @@ -429,15 +444,10 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) event.where.v = 0; event.modifiers = GetCurrentKeyModifiers(); - CGContextRef cg = m_npCgContext.context; - CGContextSaveGState(cg); - IntPoint offset = frameRect().location(); - CGContextTranslateCTM(cg, offset.x(), offset.y()); - if (!dispatchNPEvent(event)) LOG(Events, "PluginView::paint(): Paint event not accepted"); - CGContextRestoreGState(cg); + CGContextRestoreGState(cgContext); } void PluginView::invalidateRect(const IntRect& rect) diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp index fdeac2f..908e707 100644 --- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp @@ -56,6 +56,7 @@ #include "npruntime_impl.h" #include "runtime.h" #include "runtime_root.h" +#include "QWebPageClient.h" #include <QKeyEvent> #include <QWidget> #include <QX11Info> @@ -212,7 +213,9 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event) XEvent npEvent; // On UNIX NPEvent is a typedef for XEvent. npEvent.type = (event->type() == "keydown") ? 2 : 3; // ints as Qt unsets KeyPress and KeyRelease - setSharedXEventFields(npEvent, m_parentFrame->view()->hostWindow()->platformWindow()); + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + QWidget* window = QWidget::find(client->winId()); + setSharedXEventFields(npEvent, window); setXKeyEventSpecificFields(npEvent, event); if (!dispatchNPEvent(npEvent)) @@ -350,8 +353,11 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVxDisplay: if (platformPluginWidget()) *(void **)value = platformPluginWidget()->x11Info().display(); - else - *(void **)value = m_parentFrame->view()->hostWindow()->platformWindow()->x11Info().display(); + else { + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + QWidget* window = QWidget::find(client->winId()); + *(void **)value = window->x11Info().display(); + } return NPERR_NO_ERROR; case NPNVxtAppContext: @@ -396,7 +402,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVnetscapeWindow: { void* w = reinterpret_cast<void*>(value); - *((XID *)w) = m_parentFrame->view()->hostWindow()->platformWindow()->winId(); + *((XID *)w) = m_parentFrame->view()->hostWindow()->platformPageClient()->winId(); return NPERR_NO_ERROR; } @@ -451,7 +457,8 @@ bool PluginView::platformStart() } if (m_needsXEmbed) { - setPlatformWidget(new PluginContainerQt(this, m_parentFrame->view()->hostWindow()->platformWindow())); + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + setPlatformWidget(new PluginContainerQt(this, QWidget::find(client->winId()))); } else { notImplemented(); return false; diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp index 9ee8ee6..21ac2a4 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp @@ -74,17 +74,17 @@ #endif #if PLATFORM(QT) -#include <QWidget.h> +#include "QWebPageClient.h" #endif -static inline HWND windowHandleForPlatformWidget(PlatformWidget widget) +static inline HWND windowHandleForPageClient(PlatformPageClient client) { #if PLATFORM(QT) - if (!widget) + if (!client) return 0; - return widget->winId(); + return client->winId(); #else - return widget; + return client; #endif } @@ -880,7 +880,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVnetscapeWindow: { HWND* w = reinterpret_cast<HWND*>(value); - *w = windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0); + *w = windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0); return NPERR_NO_ERROR; } @@ -952,7 +952,7 @@ void PluginView::forceRedraw() if (m_isWindowed) ::UpdateWindow(platformPluginWidget()); else - ::UpdateWindow(windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0)); + ::UpdateWindow(windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0)); } bool PluginView::platformStart() @@ -970,7 +970,7 @@ bool PluginView::platformStart() if (isSelfVisible()) flags |= WS_VISIBLE; - HWND parentWindowHandle = windowHandleForPlatformWidget(m_parentFrame->view()->hostWindow()->platformWindow()); + HWND parentWindowHandle = windowHandleForPageClient(m_parentFrame->view()->hostWindow()->platformPageClient()); HWND window = ::CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags, 0, 0, 0, 0, parentWindowHandle, 0, Page::instanceHandle(), 0); diff --git a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp index ee3e75a..4852708 100644 --- a/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/FixedTableLayout.cpp @@ -188,6 +188,11 @@ int FixedTableLayout::calcWidthArray(int) return usedWidth; } +// Use a very large value (in effect infinite). But not too large! +// numeric_limits<int>::max() will too easily overflow widths. +// Keep this in synch with BLOCK_MAX_WIDTH in RenderBlock.cpp +#define TABLE_MAX_WIDTH 15000 + void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) { // FIXME: This entire calculation is incorrect for both minwidth and maxwidth. @@ -206,6 +211,24 @@ void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) minWidth = max(mw, tableWidth); maxWidth = minWidth; + + // This quirk is very similar to one that exists in RenderBlock::calcBlockPrefWidths(). + // Here's the example for this one: + /* + <table style="width:100%; background-color:red"><tr><td> + <table style="background-color:blue"><tr><td> + <table style="width:100%; background-color:green; table-layout:fixed"><tr><td> + Content + </td></tr></table> + </td></tr></table> + </td></tr></table> + */ + // In this example, the two inner tables should be as large as the outer table. + // We can achieve this effect by making the maxwidth of fixed tables with percentage + // widths be infinite. + if (m_table->style()->htmlHacks() && m_table->style()->width().isPercent() + && maxWidth < TABLE_MAX_WIDTH) + maxWidth = TABLE_MAX_WIDTH; } void FixedTableLayout::layout() diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp index 7056bca..ae0d76d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp @@ -3559,7 +3559,7 @@ void RenderBlock::calcColumnWidth() void RenderBlock::setDesiredColumnCountAndWidth(int count, int width) { - if (count == 1) { + if (count == 1 && style()->hasAutoColumnWidth()) { if (hasColumns()) { delete gColumnInfoMap->take(this); setHasColumns(false); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp index 8a38769..cea226e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp @@ -400,14 +400,21 @@ int RenderBox::horizontalScrollbarHeight() const return includeHorizontalScrollbarSize() ? layer()->horizontalScrollbarHeight() : 0; } -bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier) +bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode) { RenderLayer* l = layer(); - if (l && l->scroll(direction, granularity, multiplier)) + if (l && l->scroll(direction, granularity, multiplier)) { + if (stopNode) + *stopNode = node(); return true; + } + + if (stopNode && *stopNode && *stopNode == node()) + return true; + RenderBlock* b = containingBlock(); if (b && !b->isRenderView()) - return b->scroll(direction, granularity, multiplier); + return b->scroll(direction, granularity, multiplier, stopNode); return false; } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h index b493ae9..41c5622 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBox.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBox.h @@ -245,7 +245,7 @@ public: virtual int verticalScrollbarWidth() const; int horizontalScrollbarHeight() const; - virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f); + virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); bool canBeScrolledAndHasScrollableArea() const; virtual bool canBeProgramaticallyScrolled(bool) const; virtual void autoscroll(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h index 8fdb816..e014f22 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderForeignObject.h @@ -49,6 +49,7 @@ public: virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + virtual bool isSVGForeignObject() const { return true; } private: TransformationMatrix translationForAttributes() const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp index 08f5f57..95db43a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp @@ -2127,9 +2127,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, // Make sure the parent's clip rects have been calculated. IntRect clipRect = paintDirtyRect; if (parent()) { - ClipRects parentRects; - parentClipRects(rootLayer, parentRects, paintFlags & PaintLayerTemporaryClipRects); - clipRect = parentRects.overflowClipRect(); + clipRect = backgroundClipRect(rootLayer, paintFlags & PaintLayerTemporaryClipRects); clipRect.intersect(paintDirtyRect); } @@ -2434,9 +2432,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont if (transform() && !appliedTransform) { // Make sure the parent's clip rects have been calculated. if (parent()) { - ClipRects parentRects; - parentClipRects(rootLayer, parentRects, useTemporaryClipRects); - IntRect clipRect = parentRects.overflowClipRect(); + IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects); // Go ahead and test the enclosing clip now. if (!clipRect.contains(hitTestPoint)) return 0; @@ -2734,10 +2730,10 @@ void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipR clipRects = *parent()->clipRects(); } -void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds, - IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const +IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects) const { - if (rootLayer != this && parent()) { + IntRect backgroundRect; + if (parent()) { ClipRects parentRects; parentClipRects(rootLayer, parentRects, temporaryClipRects); backgroundRect = renderer()->style()->position() == FixedPosition ? parentRects.fixedClipRect() : @@ -2747,7 +2743,15 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa ASSERT(view); if (view && parentRects.fixed() && rootLayer->renderer() == view) backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY()); + } + return backgroundRect; +} +void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds, + IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const +{ + if (rootLayer != this && parent()) { + backgroundRect = backgroundClipRect(rootLayer, temporaryClipRects); backgroundRect.intersect(paintDirtyRect); } else backgroundRect = paintDirtyRect; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h index 16ad4d4..9d2212b 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h @@ -516,6 +516,7 @@ private: void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } void parentClipRects(const RenderLayer* rootLayer, ClipRects&, bool temporaryClipRects = false) const; + IntRect backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects) const; RenderLayer* enclosingTransformedAncestor() const; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp index 69a8f7d..941817c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.cpp @@ -58,6 +58,7 @@ static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle*); RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) : m_owningLayer(layer) , m_hasDirectlyCompositedContent(false) + , m_artificiallyInflatedBounds(false) { createGraphicsLayer(); } @@ -123,6 +124,30 @@ void RenderLayerBacking::updateLayerTransform() m_graphicsLayer->setTransform(t); } +static bool hasNonZeroTransformOrigin(const RenderObject* renderer) +{ + RenderStyle* style = renderer->style(); + return (style->transformOriginX().type() == Fixed && style->transformOriginX().value()) + || (style->transformOriginY().type() == Fixed && style->transformOriginY().value()); +} + +void RenderLayerBacking::updateCompositedBounds() +{ + IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); + + // If the element has a transform-origin that has fixed lengths, and the renderer has zero size, + // then we need to ensure that the compositing layer has non-zero size so that we can apply + // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value). + if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) { + layerBounds.setWidth(1); + layerBounds.setHeight(1); + m_artificiallyInflatedBounds = true; + } else + m_artificiallyInflatedBounds = false; + + setCompositedBounds(layerBounds); +} + void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth) { RenderLayerCompositor* layerCompositor = compositor(); @@ -134,7 +159,7 @@ void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth) // // The solution is to update compositing children of this layer here, // via updateCompositingChildrenGeometry(). - setCompositedBounds(layerCompositor->calculateCompositedBounds(m_owningLayer, m_owningLayer)); + updateCompositedBounds(); layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth); if (!m_owningLayer->parent()) { @@ -232,10 +257,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects // for a compositing layer, rootLayer is the layer itself. - ClipRects parentRects; - m_owningLayer->parentClipRects(compAncestor, parentRects, true); - IntRect parentClipRect = parentRects.overflowClipRect(); - + IntRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, true); m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation)); m_ancestorClippingLayer->setSize(parentClipRect.size()); @@ -327,7 +349,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() m_graphicsLayer->setContentsRect(contentsBox()); if (!m_hasDirectlyCompositedContent) - m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow()); + m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow() && !m_artificiallyInflatedBounds); } void RenderLayerBacking::updateInternalHierarchy() @@ -1059,7 +1081,8 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R KeyframeValueList opacityVector(AnimatedPropertyOpacity); opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity()))); opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity()))); - if (m_graphicsLayer->addAnimation(opacityVector, toRenderBox(renderer())->borderBoxRect().size(), opacityAnim, String(), beginTime)) + // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here. + if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), beginTime)) didAnimate = true; } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h index 731e741..e12aa58 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerBacking.h @@ -108,6 +108,7 @@ public: IntRect compositedBounds() const; void setCompositedBounds(const IntRect&); + void updateCompositedBounds(); FloatPoint graphicsLayerToContentsCoordinates(const GraphicsLayer*, const FloatPoint&); FloatPoint contentsToGraphicsLayerCoordinates(const GraphicsLayer*, const FloatPoint&); @@ -176,6 +177,7 @@ private: IntRect m_compositedBounds; bool m_hasDirectlyCompositedContent; + bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp index 65a9c4a..bcd1f08 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayerCompositor.cpp @@ -431,11 +431,11 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O bool haveComputedBounds = false; IntRect absBounds; - if (overlapMap && mustOverlapCompositedLayers) { + if (overlapMap && !overlapMap->isEmpty()) { // If we're testing for overlap, we only need to composite if we overlap something that is already composited. absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); haveComputedBounds = true; - mustOverlapCompositedLayers &= overlapsCompositedLayers(*overlapMap, absBounds); + mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds); } layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers); @@ -594,8 +594,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, stru if (layerBacking) { // The compositing state of all our children has been updated already, so now // we can compute and cache the composited bounds for this layer. - layerBacking->setCompositedBounds(calculateCompositedBounds(layer, layer)); - + layerBacking->updateCompositedBounds(); layerBacking->updateGraphicsLayerConfiguration(); layerBacking->updateGraphicsLayerGeometry(); @@ -675,7 +674,7 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com { if (layer != compositingAncestor) { if (RenderLayerBacking* layerBacking = layer->backing()) { - layerBacking->setCompositedBounds(calculateCompositedBounds(layer, layer)); + layerBacking->updateCompositedBounds(); layerBacking->updateGraphicsLayerGeometry(); if (updateDepth == RenderLayerBacking::CompositingChildren) return; @@ -868,10 +867,8 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const if (!computeClipRoot || computeClipRoot == layer) return false; - ClipRects parentRects; - layer->parentClipRects(computeClipRoot, parentRects, true); - - return parentRects.overflowClipRect() != ClipRects::infiniteRect(); + IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); + return backgroundRect != ClipRects::infiniteRect(); } // Return true if the given layer is a stacking context and has compositing child diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp index e6c28f7..f94f7ce 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderListBox.cpp @@ -527,8 +527,7 @@ void RenderListBox::valueChanged(Scrollbar*) if (newOffset != m_indexOffset) { m_indexOffset = newOffset; repaint(); - // Fire the scroll DOM event. - node()->dispatchEvent(eventNames().scrollEvent, false, false); + node()->dispatchEvent(Event::create(eventNames().scrollEvent, false, false)); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp index 4cbc530..1d5ed0c 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp @@ -625,6 +625,11 @@ RenderBlock* RenderObject::containingBlock() const // inline directly. if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced()) return o->containingBlock(); +#if ENABLE(SVG) + if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it + break; +#endif + o = o->parent(); } } else { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h index f361198..e5a0c16 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderObject.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderObject.h @@ -305,6 +305,7 @@ public: virtual bool isRenderPath() const { return false; } virtual bool isSVGText() const { return false; } virtual bool isSVGImage() const { return false; } + virtual bool isSVGForeignObject() const { return false; } // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width. // This is used for all computation of objectBoundingBox relative units and by SVGLocateable::getBBox(). diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp index 4f4b570..cd90854 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControl.cpp @@ -501,7 +501,7 @@ void RenderTextControl::selectionChanged(bool userTriggered) if (Frame* frame = document()->frame()) { if (frame->selection()->isRange() && userTriggered) - node()->dispatchEvent(eventNames().selectEvent, true, false); + node()->dispatchEvent(Event::create(eventNames().selectEvent, true, false)); } } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp index 8dfb858..3f0d041 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderTextControlMultiLine.cpp @@ -22,6 +22,7 @@ #include "config.h" #include "RenderTextControlMultiLine.h" +#include "Event.h" #include "EventNames.h" #include "Frame.h" #include "HTMLNames.h" @@ -50,8 +51,7 @@ void RenderTextControlMultiLine::subtreeHasChanged() if (!node()->focused()) return; - // Fire the "input" DOM event - node()->dispatchEvent(eventNames().inputEvent, true, false); + node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false)); if (Frame* frame = document()->frame()) frame->textDidChangeInTextArea(static_cast<Element*>(node())); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h index 0c417a2..9f412a0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.h @@ -3,7 +3,6 @@ * * Copyright (C) 2005 Apple Computer, Inc. * Copyright (C) 2008, 2009 Google, Inc. - * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,7 +25,6 @@ #define RenderThemeChromiumMac_h #import "RenderTheme.h" -#import <AppKit/AppKit.h> #import <wtf/HashMap.h> #import <wtf/RetainPtr.h> @@ -36,186 +34,165 @@ class WebCoreRenderThemeNotificationObserver; #endif +// This file (and its associated .mm file) is a clone of RenderThemeMac.h. See +// the .mm file for details. + namespace WebCore { - class RenderStyle; +class RenderStyle; + +class RenderThemeChromiumMac : public RenderTheme { +public: + static PassRefPtr<RenderTheme> create(); + + // A method asking if the control changes its tint when the window has focus or not. + virtual bool controlSupportsTints(const RenderObject*) const; + + // A general method asking if any control tinting is supported at all. + virtual bool supportsControlTints() const { return true; } + + virtual void adjustRepaintRect(const RenderObject*, IntRect&); + + virtual bool isControlStyled(const RenderStyle*, const BorderData&, + const FillLayer&, const Color& backgroundColor) const; + + virtual Color platformActiveSelectionBackgroundColor() const; + virtual Color platformInactiveSelectionBackgroundColor() const; + virtual Color platformActiveListBoxSelectionBackgroundColor() const; + virtual Color platformActiveListBoxSelectionForegroundColor() const; + virtual Color platformInactiveListBoxSelectionBackgroundColor() const; + virtual Color platformInactiveListBoxSelectionForegroundColor() const; + virtual Color platformFocusRingColor() const; - class RenderThemeChromiumMac : public RenderTheme { - public: - static PassRefPtr<RenderTheme> create(); + virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; } + + virtual void platformColorsDidChange(); + + // System fonts. + virtual void systemFont(int cssValueId, FontDescription&) const; + + virtual int minimumMenuListSize(RenderStyle*) const; + + virtual void adjustSliderThumbSize(RenderObject*) const; + + virtual int popupInternalPaddingLeft(RenderStyle*) const; + virtual int popupInternalPaddingRight(RenderStyle*) const; + virtual int popupInternalPaddingTop(RenderStyle*) const; + virtual int popupInternalPaddingBottom(RenderStyle*) const; + + virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - // A method to obtain the baseline position for a "leaf" control. This will only be used if a baseline - // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of - // controls that need to do this. - virtual int baselinePosition(const RenderObject*) const; + virtual Color systemColor(int cssValueId) const; - // A method asking if the control changes its tint when the window has focus or not. - virtual bool controlSupportsTints(const RenderObject*) const; +protected: + virtual bool supportsSelectionForegroundColors() const { return false; } - // A general method asking if any control tinting is supported at all. - virtual bool supportsControlTints() const { return true; } + virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual void adjustRepaintRect(const RenderObject*, IntRect&); + virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool isControlStyled(const RenderStyle*, const BorderData&, - const FillLayer&, const Color& backgroundColor) const; + virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual Color platformActiveSelectionBackgroundColor() const; - virtual Color platformInactiveSelectionBackgroundColor() const; - virtual Color platformActiveListBoxSelectionBackgroundColor() const; + virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual Color platformFocusRingColor() const; - - virtual void platformColorsDidChange(); + virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - // System fonts. - virtual void systemFont(int cssValueId, FontDescription&) const; + virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual int minimumMenuListSize(RenderStyle*) const; + virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual void adjustSliderThumbSize(RenderObject*) const; - - virtual int popupInternalPaddingLeft(RenderStyle*) const; - virtual int popupInternalPaddingRight(RenderStyle*) const; - virtual int popupInternalPaddingTop(RenderStyle*) const; - virtual int popupInternalPaddingBottom(RenderStyle*) const; - - virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; } + virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + +#if ENABLE(VIDEO) + virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaControlsBackground(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + + // Media controls + virtual String extraMediaControlsStyleSheet(); +#endif + +private: + RenderThemeChromiumMac(); + virtual ~RenderThemeChromiumMac(); + + IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; + + FloatRect convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const; - virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + // Get the control size based off the font. Used by some of the controls (like buttons). + NSControlSize controlSizeForFont(RenderStyle*) const; + NSControlSize controlSizeForSystemFont(RenderStyle*) const; + void setControlSize(NSCell*, const IntSize* sizes, const IntSize& minSize, float zoomLevel = 1.0f); + void setSizeFromFont(RenderStyle*, const IntSize* sizes) const; + IntSize sizeForFont(RenderStyle*, const IntSize* sizes) const; + IntSize sizeForSystemFont(RenderStyle*, const IntSize* sizes) const; + void setFontFromControlSize(CSSStyleSelector*, RenderStyle*, NSControlSize) const; + + void updateActiveState(NSCell*, const RenderObject*); + void updateCheckedState(NSCell*, const RenderObject*); + void updateEnabledState(NSCell*, const RenderObject*); + void updateFocusedState(NSCell*, const RenderObject*); + void updatePressedState(NSCell*, const RenderObject*); + + // Helpers for adjusting appearance and for painting + + void setPopupButtonCellState(const RenderObject*, const IntRect&); + const IntSize* popupButtonSizes() const; + const int* popupButtonMargins() const; + const int* popupButtonPadding(NSControlSize) const; + void paintMenuListButtonGradients(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + const IntSize* menuListSizes() const; + + const IntSize* searchFieldSizes() const; + const IntSize* cancelButtonSizes() const; + const IntSize* resultsButtonSizes() const; + void setSearchCellState(RenderObject*, const IntRect&); + void setSearchFieldSize(RenderStyle*) const; + + NSPopUpButtonCell* popupButton() const; + NSSearchFieldCell* search() const; + NSMenu* searchMenuTemplate() const; + NSSliderCell* sliderThumbHorizontal() const; + NSSliderCell* sliderThumbVertical() const; + +private: + mutable RetainPtr<NSPopUpButtonCell> m_popupButton; + mutable RetainPtr<NSSearchFieldCell> m_search; + mutable RetainPtr<NSMenu> m_searchMenuTemplate; + mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal; + mutable RetainPtr<NSSliderCell> m_sliderThumbVertical; - virtual Color systemColor(int cssValueId) const; + bool m_isSliderThumbHorizontalPressed; + bool m_isSliderThumbVerticalPressed; - protected: - virtual bool supportsSelectionForegroundColors() const { return false; } + mutable HashMap<int, RGBA32> m_systemColorCache; - // Methods for each appearance value. - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setCheckboxSize(RenderStyle*) const; - - virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setRadioSize(RenderStyle*) const; - - virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void setButtonSize(RenderStyle*) const; - - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - - virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - - private: - RenderThemeChromiumMac(); - virtual ~RenderThemeChromiumMac(); - - IntRect inflateRect(const IntRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const; - - // Get the control size based off the font. Used by some of the controls (like buttons). - NSControlSize controlSizeForFont(RenderStyle*) const; - NSControlSize controlSizeForSystemFont(RenderStyle*) const; - void setControlSize(NSCell*, const IntSize* sizes, const IntSize& minSize, float zoomLevel = 1.0f); - void setSizeFromFont(RenderStyle*, const IntSize* sizes) const; - IntSize sizeForFont(RenderStyle*, const IntSize* sizes) const; - IntSize sizeForSystemFont(RenderStyle*, const IntSize* sizes) const; - void setFontFromControlSize(CSSStyleSelector*, RenderStyle*, NSControlSize) const; - - void updateActiveState(NSCell*, const RenderObject*); - void updateCheckedState(NSCell*, const RenderObject*); - void updateEnabledState(NSCell*, const RenderObject*); - void updateFocusedState(NSCell*, const RenderObject*); - void updatePressedState(NSCell*, const RenderObject*); - - // Helpers for adjusting appearance and for painting - const IntSize* checkboxSizes() const; - const int* checkboxMargins() const; - void setCheckboxCellState(const RenderObject*, const IntRect&); - - const IntSize* radioSizes() const; - const int* radioMargins() const; - void setRadioCellState(const RenderObject*, const IntRect&); - - void setButtonPaddingFromControlSize(RenderStyle*, NSControlSize) const; - const IntSize* buttonSizes() const; - const int* buttonMargins() const; - void setButtonCellState(const RenderObject*, const IntRect&); - - void setPopupButtonCellState(const RenderObject*, const IntRect&); - const IntSize* popupButtonSizes() const; - const int* popupButtonMargins() const; - const int* popupButtonPadding(NSControlSize) const; - void paintMenuListButtonGradients(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - const IntSize* menuListSizes() const; - - const IntSize* searchFieldSizes() const; - const IntSize* cancelButtonSizes() const; - const IntSize* resultsButtonSizes() const; - void setSearchCellState(RenderObject*, const IntRect&); - void setSearchFieldSize(RenderStyle*) const; - - NSButtonCell* checkbox() const; - NSButtonCell* radio() const; - NSButtonCell* button() const; - NSPopUpButtonCell* popupButton() const; - NSSearchFieldCell* search() const; - NSMenu* searchMenuTemplate() const; - NSSliderCell* sliderThumbHorizontal() const; - NSSliderCell* sliderThumbVertical() const; - - private: - mutable RetainPtr<NSButtonCell> m_checkbox; - mutable RetainPtr<NSButtonCell> m_radio; - mutable RetainPtr<NSButtonCell> m_button; - mutable RetainPtr<NSPopUpButtonCell> m_popupButton; - mutable RetainPtr<NSSearchFieldCell> m_search; - mutable RetainPtr<NSMenu> m_searchMenuTemplate; - mutable RetainPtr<NSSliderCell> m_sliderThumbHorizontal; - mutable RetainPtr<NSSliderCell> m_sliderThumbVertical; - - bool m_isSliderThumbHorizontalPressed; - bool m_isSliderThumbVerticalPressed; - - mutable HashMap<int, RGBA32> m_systemColorCache; - - RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver; - }; + RetainPtr<WebCoreRenderThemeNotificationObserver> m_notificationObserver; + bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); +}; } // namespace WebCore -#endif +#endif // RenderThemeChromiumMac_h diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm index 659a0c6..695f9fa 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumMac.mm @@ -1,7 +1,6 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008, 2009 Google, Inc. - * Copyright (C) 2009 Kenneth Rohde Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,26 +18,18 @@ * Boston, MA 02110-1301, USA. */ -// FIXME: we still need to figure out if passing a null view to the cell -// drawing routines will work. I expect not, and if that's the case we'll have -// to figure out something else. For now, at least leave the lines commented -// in, but the procurement of the view if 0'd. - #import "config.h" #import "RenderThemeChromiumMac.h" -#import <Carbon/Carbon.h> -#import <Cocoa/Cocoa.h> -#import <math.h> - #import "BitmapImage.h" #import "ChromiumBridge.h" #import "ColorMac.h" #import "CSSStyleSelector.h" #import "CSSValueKeywords.h" +#import "Document.h" #import "Element.h" -#import "FoundationExtras.h" #import "FrameView.h" +#import "Gradient.h" #import "GraphicsContext.h" #import "HTMLInputElement.h" #import "HTMLMediaElement.h" @@ -50,9 +41,14 @@ #import "RenderSlider.h" #import "RenderView.h" #import "SharedBuffer.h" -#import "TimeRanges.h" +#import "UserAgentStyleSheets.h" #import "WebCoreSystemInterface.h" +#import "UserAgentStyleSheets.h" +#import <Carbon/Carbon.h> +#import <Cocoa/Cocoa.h> #import <wtf/RetainPtr.h> +#import <wtf/StdLibExtras.h> +#import <math.h> #ifdef BUILDING_ON_TIGER typedef int NSInteger; @@ -61,6 +57,25 @@ typedef unsigned NSUInteger; using std::min; +// This file (and its associated .h file) is a clone of RenderThemeMac.mm. +// Because the original file is designed to run in-process inside a Cocoa view, +// we must maintain a fork. Please maintain this file by performing parallel +// changes to it. +// +// The only changes from RenderThemeMac should be: +// - The classname change from RenderThemeMac to RenderThemeChromiumMac. +// - The introduction of RTCMFlippedView and FlippedView() and its use as the +// parent view for cell rendering. +// - In platformFocusRingColor(), the use of ChromiumBridge to determine if +// we're in layout test mode. +// - updateActiveState() and its use to update the cells' visual appearance. +// - All the paintMedia*() functions and extraMediaControlsStyleSheet() +// are forked from RenderThemeChromiumSkia instead of RenderThemeMac. +// +// For all other differences, if it was introduced in this file, then the +// maintainer forgot to include it in the list; otherwise it is an update that +// should have been applied to this file but was not. + // The methods in this file are specific to the Mac OS X platform. // FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeSafari. @@ -85,48 +100,66 @@ using std::min; return self; } -- (void)systemColorsDidChange:(NSNotification *)notification +- (void)systemColorsDidChange:(NSNotification *)unusedNotification { - ASSERT([[notification name] isEqualToString:NSSystemColorsDidChangeNotification]); + ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]); _theme->platformColorsDidChange(); } @end +@interface RTCMFlippedView : NSView +{} + +- (BOOL)isFlipped; +- (NSText *)currentEditor; + +@end + +@implementation RTCMFlippedView + +- (BOOL)isFlipped { + return [[NSGraphicsContext currentContext] isFlipped]; +} + +- (NSText *)currentEditor { + return nil; +} + +@end + namespace WebCore { using namespace HTMLNames; enum { - TopMargin, - RightMargin, - BottomMargin, - LeftMargin + topMargin, + rightMargin, + bottomMargin, + leftMargin }; enum { - TopPadding, - RightPadding, - BottomPadding, - LeftPadding + topPadding, + rightPadding, + bottomPadding, + leftPadding }; -// In our Mac port, we don't define PLATFORM(MAC) and thus don't pick up the -// |operator NSRect()| on WebCore::IntRect and FloatRect. This substitues for -// that missing conversion operator. -NSRect IntRectToNSRect(const IntRect & rect) +// In Snow Leopard, many cells only check to see if the view they're passed is +// flipped, and if a nil view is passed, neglect to check if the current +// graphics context is flipped. Thus we pass a sham view to them, one whose +// flipped state just reflects the state of the context. +NSView* FlippedView() { - return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); + static NSView* view = [[RTCMFlippedView alloc] init]; + return view; } -NSRect FloatRectToNSRect(const FloatRect & rect) +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*) { - return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); -} - -IntRect NSRectToIntRect(const NSRect & rect) -{ - return IntRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + static RenderTheme* rt = RenderThemeChromiumMac::create().releaseRef(); + return rt; } PassRefPtr<RenderTheme> RenderThemeChromiumMac::create() @@ -134,12 +167,6 @@ PassRefPtr<RenderTheme> RenderThemeChromiumMac::create() return adoptRef(new RenderThemeChromiumMac); } -PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) -{ - static RenderTheme* rt = RenderThemeChromiumMac::create().releaseRef(); - return rt; -} - RenderThemeChromiumMac::RenderThemeChromiumMac() : m_isSliderThumbHorizontalPressed(false) , m_isSliderThumbVerticalPressed(false) @@ -174,6 +201,16 @@ Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() co return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent])); } +Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const +{ + return Color::white; +} + +Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const +{ + return Color::black; +} + Color RenderThemeChromiumMac::platformFocusRingColor() const { if (ChromiumBridge::layoutTestMode()) @@ -182,6 +219,11 @@ Color RenderThemeChromiumMac::platformFocusRingColor() const return systemColor(CSSValueWebkitFocusRingColor); } +Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const +{ + return platformInactiveSelectionBackgroundColor(); +} + static FontWeight toFontWeight(NSInteger appKitFontWeight) { ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15); @@ -211,51 +253,51 @@ static FontWeight toFontWeight(NSInteger appKitFontWeight) void RenderThemeChromiumMac::systemFont(int cssValueId, FontDescription& fontDescription) const { - static FontDescription systemFont; - static FontDescription smallSystemFont; - static FontDescription menuFont; - static FontDescription labelFont; - static FontDescription miniControlFont; - static FontDescription smallControlFont; - static FontDescription controlFont; + DEFINE_STATIC_LOCAL(FontDescription, systemFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, smallSystemFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, menuFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, labelFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, miniControlFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, smallControlFont, ()); + DEFINE_STATIC_LOCAL(FontDescription, controlFont, ()); FontDescription* cachedDesc; NSFont* font = nil; switch (cssValueId) { - case CSSValueSmallCaption: - cachedDesc = &smallSystemFont; - if (!smallSystemFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; - break; - case CSSValueMenu: - cachedDesc = &menuFont; - if (!menuFont.isAbsoluteSize()) - font = [NSFont menuFontOfSize:[NSFont systemFontSize]]; - break; - case CSSValueStatusBar: - cachedDesc = &labelFont; - if (!labelFont.isAbsoluteSize()) - font = [NSFont labelFontOfSize:[NSFont labelFontSize]]; - break; - case CSSValueWebkitMiniControl: - cachedDesc = &miniControlFont; - if (!miniControlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]]; - break; - case CSSValueWebkitSmallControl: - cachedDesc = &smallControlFont; - if (!smallControlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; - break; - case CSSValueWebkitControl: - cachedDesc = &controlFont; - if (!controlFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; - break; - default: - cachedDesc = &systemFont; - if (!systemFont.isAbsoluteSize()) - font = [NSFont systemFontOfSize:[NSFont systemFontSize]]; + case CSSValueSmallCaption: + cachedDesc = &smallSystemFont; + if (!smallSystemFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; + break; + case CSSValueMenu: + cachedDesc = &menuFont; + if (!menuFont.isAbsoluteSize()) + font = [NSFont menuFontOfSize:[NSFont systemFontSize]]; + break; + case CSSValueStatusBar: + cachedDesc = &labelFont; + if (!labelFont.isAbsoluteSize()) + font = [NSFont labelFontOfSize:[NSFont labelFontSize]]; + break; + case CSSValueWebkitMiniControl: + cachedDesc = &miniControlFont; + if (!miniControlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]]; + break; + case CSSValueWebkitSmallControl: + cachedDesc = &smallControlFont; + if (!smallControlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + break; + case CSSValueWebkitControl: + cachedDesc = &controlFont; + if (!controlFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; + break; + default: + cachedDesc = &systemFont; + if (!systemFont.isAbsoluteSize()) + font = [NSFont systemFontOfSize:[NSFont systemFontSize]]; } if (font) { @@ -272,7 +314,7 @@ void RenderThemeChromiumMac::systemFont(int cssValueId, FontDescription& fontDes static RGBA32 convertNSColorToColor(NSColor *color) { - NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; if (colorInColorSpace) { static const double scaleFactor = nextafter(256.0, 0.0); return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]), @@ -292,7 +334,7 @@ static RGBA32 convertNSColorToColor(NSColor *color) samplesPerPixel:4 hasAlpha:YES isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace + colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4 bitsPerPixel:32]; @@ -319,7 +361,7 @@ static RGBA32 menuBackgroundColor() samplesPerPixel:4 hasAlpha:YES isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace + colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4 bitsPerPixel:32]; @@ -351,101 +393,101 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const Color color; switch (cssValueId) { - case CSSValueActiveborder: - color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); - break; - case CSSValueActivecaption: - color = convertNSColorToColor([NSColor windowFrameTextColor]); - break; - case CSSValueAppworkspace: - color = convertNSColorToColor([NSColor headerColor]); - break; - case CSSValueBackground: - // Use theme independent default - break; - case CSSValueButtonface: - // We use this value instead of NSColor's controlColor to avoid website incompatibilities. - // We may want to change this to use the NSColor in future. - color = 0xFFC0C0C0; - break; - case CSSValueButtonhighlight: - color = convertNSColorToColor([NSColor controlHighlightColor]); - break; - case CSSValueButtonshadow: - color = convertNSColorToColor([NSColor controlShadowColor]); - break; - case CSSValueButtontext: - color = convertNSColorToColor([NSColor controlTextColor]); - break; - case CSSValueCaptiontext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueGraytext: - color = convertNSColorToColor([NSColor disabledControlTextColor]); - break; - case CSSValueHighlight: - color = convertNSColorToColor([NSColor selectedTextBackgroundColor]); - break; - case CSSValueHighlighttext: - color = convertNSColorToColor([NSColor selectedTextColor]); - break; - case CSSValueInactiveborder: - color = convertNSColorToColor([NSColor controlBackgroundColor]); - break; - case CSSValueInactivecaption: - color = convertNSColorToColor([NSColor controlBackgroundColor]); - break; - case CSSValueInactivecaptiontext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueInfobackground: - // There is no corresponding NSColor for this so we use a hard coded value. - color = 0xFFFBFCC5; - break; - case CSSValueInfotext: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueMenu: - color = menuBackgroundColor(); - break; - case CSSValueMenutext: - color = convertNSColorToColor([NSColor selectedMenuItemTextColor]); - break; - case CSSValueScrollbar: - color = convertNSColorToColor([NSColor scrollBarColor]); - break; - case CSSValueText: - color = convertNSColorToColor([NSColor textColor]); - break; - case CSSValueThreeddarkshadow: - color = convertNSColorToColor([NSColor controlDarkShadowColor]); - break; - case CSSValueThreedshadow: - color = convertNSColorToColor([NSColor shadowColor]); - break; - case CSSValueThreedface: - // We use this value instead of NSColor's controlColor to avoid website incompatibilities. - // We may want to change this to use the NSColor in future. - color = 0xFFC0C0C0; - break; - case CSSValueThreedhighlight: - color = convertNSColorToColor([NSColor highlightColor]); - break; - case CSSValueThreedlightshadow: - color = convertNSColorToColor([NSColor controlLightHighlightColor]); - break; - case CSSValueWebkitFocusRingColor: - color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); - break; - case CSSValueWindow: - color = convertNSColorToColor([NSColor windowBackgroundColor]); - break; - case CSSValueWindowframe: - color = convertNSColorToColor([NSColor windowFrameColor]); - break; - case CSSValueWindowtext: - color = convertNSColorToColor([NSColor windowFrameTextColor]); - break; + case CSSValueActiveborder: + color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + break; + case CSSValueActivecaption: + color = convertNSColorToColor([NSColor windowFrameTextColor]); + break; + case CSSValueAppworkspace: + color = convertNSColorToColor([NSColor headerColor]); + break; + case CSSValueBackground: + // Use theme independent default + break; + case CSSValueButtonface: + // We use this value instead of NSColor's controlColor to avoid website incompatibilities. + // We may want to change this to use the NSColor in future. + color = 0xFFC0C0C0; + break; + case CSSValueButtonhighlight: + color = convertNSColorToColor([NSColor controlHighlightColor]); + break; + case CSSValueButtonshadow: + color = convertNSColorToColor([NSColor controlShadowColor]); + break; + case CSSValueButtontext: + color = convertNSColorToColor([NSColor controlTextColor]); + break; + case CSSValueCaptiontext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueGraytext: + color = convertNSColorToColor([NSColor disabledControlTextColor]); + break; + case CSSValueHighlight: + color = convertNSColorToColor([NSColor selectedTextBackgroundColor]); + break; + case CSSValueHighlighttext: + color = convertNSColorToColor([NSColor selectedTextColor]); + break; + case CSSValueInactiveborder: + color = convertNSColorToColor([NSColor controlBackgroundColor]); + break; + case CSSValueInactivecaption: + color = convertNSColorToColor([NSColor controlBackgroundColor]); + break; + case CSSValueInactivecaptiontext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueInfobackground: + // There is no corresponding NSColor for this so we use a hard coded value. + color = 0xFFFBFCC5; + break; + case CSSValueInfotext: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueMenu: + color = menuBackgroundColor(); + break; + case CSSValueMenutext: + color = convertNSColorToColor([NSColor selectedMenuItemTextColor]); + break; + case CSSValueScrollbar: + color = convertNSColorToColor([NSColor scrollBarColor]); + break; + case CSSValueText: + color = convertNSColorToColor([NSColor textColor]); + break; + case CSSValueThreeddarkshadow: + color = convertNSColorToColor([NSColor controlDarkShadowColor]); + break; + case CSSValueThreedshadow: + color = convertNSColorToColor([NSColor shadowColor]); + break; + case CSSValueThreedface: + // We use this value instead of NSColor's controlColor to avoid website incompatibilities. + // We may want to change this to use the NSColor in future. + color = 0xFFC0C0C0; + break; + case CSSValueThreedhighlight: + color = convertNSColorToColor([NSColor highlightColor]); + break; + case CSSValueThreedlightshadow: + color = convertNSColorToColor([NSColor controlLightHighlightColor]); + break; + case CSSValueWebkitFocusRingColor: + color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + break; + case CSSValueWindow: + color = convertNSColorToColor([NSColor windowBackgroundColor]); + break; + case CSSValueWindowframe: + color = convertNSColorToColor([NSColor windowFrameColor]); + break; + case CSSValueWindowtext: + color = convertNSColorToColor([NSColor windowFrameTextColor]); + break; } if (!color.isValid()) @@ -458,7 +500,7 @@ Color RenderThemeChromiumMac::systemColor(int cssValueId) const } bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const BorderData& border, - const FillLayer& background, const Color& backgroundColor) const + const FillLayer& background, const Color& backgroundColor) const { if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart) return style->border() != border; @@ -473,62 +515,32 @@ bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const Bor return RenderTheme::isControlStyled(style, border, background, backgroundColor); } -// FIXME: Use the code from the old upstream version, before it was converted to the new theme API in r37731. void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r) { - float zoomLevel = o->style()->effectiveZoom(); - - switch (o->style()->appearance()) { - case CheckboxPart: { - // Since we query the prototype cell, we need to update its state to match. - setCheckboxCellState(o, r); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - IntSize size = checkboxSizes()[[checkbox() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(size.width() * zoomLevel); - r = inflateRect(r, size, checkboxMargins(), zoomLevel); - break; + ControlPart part = o->style()->appearance(); + +#if USE(NEW_THEME) + switch (part) { + case CheckboxPart: + case RadioPart: + case PushButtonPart: + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + return RenderTheme::adjustRepaintRect(o, r); + default: + break; } - case RadioPart: { - // Since we query the prototype cell, we need to update its state to match. - setRadioCellState(o, r); +#endif - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - IntSize size = radioSizes()[[radio() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(size.width() * zoomLevel); - r = inflateRect(r, size, radioMargins(), zoomLevel); - break; - } - case PushButtonPart: - case DefaultButtonPart: - case ButtonPart: { - // Since we query the prototype cell, we need to update its state to match. - setButtonCellState(o, r); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - if ([button() bezelStyle] == NSRoundedBezelStyle) { - IntSize size = buttonSizes()[[button() controlSize]]; - size.setHeight(size.height() * zoomLevel); - size.setWidth(r.width()); - r = inflateRect(r, size, buttonMargins(), zoomLevel); - } - break; - } - case MenulistPart: { + float zoomLevel = o->style()->effectiveZoom(); + + if (part == MenulistPart) { setPopupButtonCellState(o, r); IntSize size = popupButtonSizes()[[popupButton() controlSize]]; size.setHeight(size.height() * zoomLevel); size.setWidth(r.width()); r = inflateRect(r, size, popupButtonMargins(), zoomLevel); - break; - } - default: - break; } } @@ -536,20 +548,42 @@ IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& siz { // Only do the inflation if the available width/height are too small. Otherwise try to // fit the glow/check space into the available box's width/height. - int widthDelta = r.width() - (size.width() + margins[LeftMargin] * zoomLevel + margins[RightMargin] * zoomLevel); - int heightDelta = r.height() - (size.height() + margins[TopMargin] * zoomLevel + margins[BottomMargin] * zoomLevel); + int widthDelta = r.width() - (size.width() + margins[leftMargin] * zoomLevel + margins[rightMargin] * zoomLevel); + int heightDelta = r.height() - (size.height() + margins[topMargin] * zoomLevel + margins[bottomMargin] * zoomLevel); IntRect result(r); if (widthDelta < 0) { - result.setX(result.x() - margins[LeftMargin] * zoomLevel); + result.setX(result.x() - margins[leftMargin] * zoomLevel); result.setWidth(result.width() - widthDelta); } if (heightDelta < 0) { - result.setY(result.y() - margins[TopMargin] * zoomLevel); + result.setY(result.y() - margins[topMargin] * zoomLevel); result.setHeight(result.height() - heightDelta); } return result; } +FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const +{ + FloatRect partRect(inputRect); + + // Compute an offset between the part renderer and the input renderer + FloatSize offsetFromInputRenderer; + const RenderObject* renderer = partRenderer; + while (renderer && renderer != inputRenderer) { + RenderObject* containingRenderer = renderer->container(); + offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer); + renderer = containingRenderer; + } + // If the input renderer was not a container, something went wrong + ASSERT(renderer == inputRenderer); + // Move the rect into partRenderer's coords + partRect.move(offsetFromInputRenderer); + // Account for the local drawing offset (tx, ty) + partRect.move(r.x(), r.y()); + + return partRect; +} + // Updates the control tint (a.k.a. active state) of |cell| (from |o|). // In the Chromium port, the renderer runs as a background process and controls' // NSCell(s) lack a parent NSView. Therefore controls don't have their tint @@ -609,19 +643,6 @@ void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject [cell setHighlighted:pressed]; } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -int RenderThemeChromiumMac::baselinePosition(const RenderObject* o) const -{ - if (!o->isBox()) - return 0; - - if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart) { - const RenderBox* box = toRenderBox(o); - return box->marginTop() + box->height() - 2 * o->style()->effectiveZoom(); // The baseline is 2px up from the bottom of the checkbox/radio in AppKit. - } - return RenderTheme::baselinePosition(o); -} - bool RenderThemeChromiumMac::controlSupportsTints(const RenderObject* o) const { // An alternate way to implement this would be to get the appropriate cell object @@ -693,7 +714,7 @@ void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* style->setHeight(Length(size.height(), Fixed)); } -void RenderThemeChromiumMac::setFontFromControlSize(CSSStyleSelector* selector, RenderStyle* style, NSControlSize controlSize) const +void RenderThemeChromiumMac::setFontFromControlSize(CSSStyleSelector*, RenderStyle* style, NSControlSize controlSize) const { FontDescription fontDescription; fontDescription.setIsAbsoluteSize(true); @@ -721,352 +742,10 @@ NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* styl return NSMiniControlSize; } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setCheckboxCellState(o, r); - - paintInfo.context->save(); - - float zoomLevel = o->style()->effectiveZoom(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - NSButtonCell* checkbox = this->checkbox(); - IntSize size = checkboxSizes()[[checkbox controlSize]]; - size.setWidth(size.width() * zoomLevel); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = inflateRect(r, size, checkboxMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - [checkbox drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:nil]; - [checkbox setControlView:nil]; - - paintInfo.context->restore(); - - return false; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::checkboxSizes() const -{ - static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::checkboxMargins() const -{ - static const int margins[3][4] = - { - { 3, 4, 4, 2 }, - { 4, 3, 3, 3 }, - { 4, 3, 3, 3 }, - }; - return margins[[checkbox() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setCheckboxCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* checkbox = this->checkbox(); - - // Set the control size based off the rectangle we're painting into. - setControlSize(checkbox, checkboxSizes(), r.size(), o->style()->effectiveZoom()); - - // Update the various states we respond to. - updateActiveState(checkbox, o); - updateCheckedState(checkbox, o); - updateEnabledState(checkbox, o); - updatePressedState(checkbox, o); - updateFocusedState(checkbox, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setCheckboxSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, checkboxSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintRadio(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setRadioCellState(o, r); - - paintInfo.context->save(); - - float zoomLevel = o->style()->effectiveZoom(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - NSButtonCell* radio = this->radio(); - IntSize size = radioSizes()[[radio controlSize]]; - size.setWidth(size.width() * zoomLevel); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = inflateRect(r, size, radioMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - [radio drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:nil]; - [radio setControlView:nil]; - - paintInfo.context->restore(); - - return false; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::radioSizes() const -{ - static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::radioMargins() const -{ - static const int margins[3][4] = - { - { 2, 2, 4, 2 }, - { 3, 2, 3, 2 }, - { 1, 0, 2, 0 }, - }; - return margins[[radio() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setRadioCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* radio = this->radio(); - - // Set the control size based off the rectangle we're painting into. - setControlSize(radio, radioSizes(), r.size(), o->style()->effectiveZoom()); - - // Update the various states we respond to. - updateActiveState(radio, o); - updateCheckedState(radio, o); - updateEnabledState(radio, o); - updatePressedState(radio, o); - updateFocusedState(radio, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setRadioSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, radioSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonPaddingFromControlSize(RenderStyle* style, NSControlSize size) const -{ - // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large - // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is - // by definition constrained, since we select mini only for small cramped environments. - // This also guarantees the HTML4 <button> will match our rendering by default, since we're using a consistent - // padding. - const int padding = 8 * style->effectiveZoom(); - style->setPaddingLeft(Length(padding, Fixed)); - style->setPaddingRight(Length(padding, Fixed)); - style->setPaddingTop(Length(0, Fixed)); - style->setPaddingBottom(Length(0, Fixed)); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const -{ - // There are three appearance constants for buttons. - // (1) Push-button is the constant for the default Aqua system button. Push buttons will not scale vertically and will not allow - // custom fonts or colors. <input>s use this constant. This button will allow custom colors and font weights/variants but won't - // scale vertically. - // (2) square-button is the constant for the square button. This button will allow custom fonts and colors and will scale vertically. - // (3) Button is the constant that means "pick the best button as appropriate." <button>s use this constant. This button will - // also scale vertically and allow custom fonts and colors. It will attempt to use Aqua if possible and will make this determination - // solely on the rectangle of the control. - - // Determine our control size based off our font. - NSControlSize controlSize = controlSizeForFont(style); - - if (style->appearance() == PushButtonPart) { - // Ditch the border. - style->resetBorder(); - - // Height is locked to auto. - style->setHeight(Length(Auto)); - - // White-space is locked to pre - style->setWhiteSpace(PRE); - - // Set the button's vertical size. - setButtonSize(style); - - // Add in the padding that we'd like to use. - setButtonPaddingFromControlSize(style, controlSize); - - // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out - // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate - // system font for the control size instead. - setFontFromControlSize(selector, style, controlSize); - } else { - // Set a min-height so that we can't get smaller than the mini button. - style->setMinHeight(Length(static_cast<int>(15 * style->effectiveZoom()), Fixed)); - - // Reset the top and bottom borders. - style->resetBorderTop(); - style->resetBorderBottom(); - } - - style->setBoxShadow(0); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const IntSize* RenderThemeChromiumMac::buttonSizes() const -{ - static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; - return sizes; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -const int* RenderThemeChromiumMac::buttonMargins() const -{ - static const int margins[3][4] = - { - { 4, 6, 7, 6 }, - { 4, 5, 6, 5 }, - { 0, 1, 1, 1 }, - }; - return margins[[button() controlSize]]; -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonSize(RenderStyle* style) const -{ - // If the width and height are both specified, then we have nothing to do. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; - - // Use the font size to determine the intrinsic width of the control. - setSizeFromFont(style, buttonSizes()); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -void RenderThemeChromiumMac::setButtonCellState(const RenderObject* o, const IntRect& r) -{ - NSButtonCell* button = this->button(); - - // Set the control size based off the rectangle we're painting into. - if (o->style()->appearance() == SquareButtonPart || - r.height() > buttonSizes()[NSRegularControlSize].height() * o->style()->effectiveZoom()) { - // Use the square button - if ([button bezelStyle] != NSShadowlessSquareBezelStyle) - [button setBezelStyle:NSShadowlessSquareBezelStyle]; - } else if ([button bezelStyle] != NSRoundedBezelStyle) - [button setBezelStyle:NSRoundedBezelStyle]; - - setControlSize(button, buttonSizes(), r.size(), o->style()->effectiveZoom()); - - NSWindow *window = [nil window]; - BOOL isDefaultButton = (isDefault(o) && [window isKeyWindow]); - [button setKeyEquivalent:(isDefaultButton ? @"\r" : @"")]; - - // Update the various states we respond to. - updateActiveState(button, o); - updateCheckedState(button, o); - updateEnabledState(button, o); - updatePressedState(button, o); - updateFocusedState(button, o); -} - -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -bool RenderThemeChromiumMac::paintButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) -{ - NSButtonCell* button = this->button(); - LocalCurrentGraphicsContext localContext(paintInfo.context); - - // Determine the width and height needed for the control and prepare the cell for painting. - setButtonCellState(o, r); - - paintInfo.context->save(); - - // We inflate the rect as needed to account for padding included in the cell to accommodate the button - // shadow. We don't consider this part of the bounds of the control in WebKit. - float zoomLevel = o->style()->effectiveZoom(); - IntSize size = buttonSizes()[[button controlSize]]; - size.setWidth(r.width()); - size.setHeight(size.height() * zoomLevel); - IntRect inflatedRect = r; - if ([button bezelStyle] == NSRoundedBezelStyle) { - // Center the button within the available space. - if (inflatedRect.height() > size.height()) { - inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - size.height()) / 2); - inflatedRect.setHeight(size.height()); - } - - // Now inflate it to account for the shadow. - inflatedRect = inflateRect(inflatedRect, size, buttonMargins(), zoomLevel); - - if (zoomLevel != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomLevel); - inflatedRect.setHeight(inflatedRect.height() / zoomLevel); - paintInfo.context->translate(inflatedRect.x(), inflatedRect.y()); - paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel)); - paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - } - - NSView *view = nil; - NSWindow *window = [view window]; - NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell]; - - if (isDefault(o) && [window isKeyWindow]) { - [window setDefaultButtonCell:button]; - wkAdvanceDefaultButtonPulseAnimation(button); - } else if ([previousDefaultButtonCell isEqual:button]) - [window setDefaultButtonCell:nil]; - - [button drawWithFrame:NSRect(IntRectToNSRect(inflatedRect)) inView:view]; - [button setControlView:nil]; - - if (![previousDefaultButtonCell isEqual:button]) - [window setDefaultButtonCell:previousDefaultButtonCell]; - - paintInfo.context->restore(); - - return false; -} - bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawBezeledTextFieldCell(IntRectToNSRect(r), isEnabled(o) && !isReadOnlyControl(o)); + wkDrawBezeledTextFieldCell(r, isEnabled(o) && !isReadOnlyControl(o)); return false; } @@ -1074,7 +753,7 @@ void RenderThemeChromiumMac::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle { } -bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { if (paintInfo.context->paintingDisabled()) return true; @@ -1088,7 +767,7 @@ bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject* o, const Rende bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawBezeledTextArea(IntRectToNSRect(r), isEnabled(o) && !isReadOnlyControl(o)); + wkDrawBezeledTextArea(r, isEnabled(o) && !isReadOnlyControl(o)); return false; } @@ -1126,8 +805,6 @@ const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - setPopupButtonCellState(o, r); NSPopUpButtonCell* popupButton = this->popupButton(); @@ -1157,7 +834,7 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject:: paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y()); } - [popupButton drawWithFrame:IntRectToNSRect(inflatedRect) inView:nil]; + [popupButton drawWithFrame:inflatedRect inView:FlippedView()]; [popupButton setControlView:nil]; paintInfo.context->restore(); @@ -1165,19 +842,19 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const RenderObject:: return false; } -static const float baseFontSize = 11.0f; -static const float baseArrowHeight = 4.0f; -static const float baseArrowWidth = 5.0f; -static const float baseSpaceBetweenArrows = 2.0f; -static const int arrowPaddingLeft = 6; -static const int arrowPaddingRight = 6; -static const int paddingBeforeSeparator = 4; -static const int baseBorderRadius = 5; -static const int styledPopupPaddingLeft = 8; -static const int styledPopupPaddingTop = 1; -static const int styledPopupPaddingBottom = 2; +const float baseFontSize = 11.0f; +const float baseArrowHeight = 4.0f; +const float baseArrowWidth = 5.0f; +const float baseSpaceBetweenArrows = 2.0f; +const int arrowPaddingLeft = 6; +const int arrowPaddingRight = 6; +const int paddingBeforeSeparator = 4; +const int baseBorderRadius = 5; +const int styledPopupPaddingLeft = 8; +const int styledPopupPaddingTop = 1; +const int styledPopupPaddingBottom = 2; -static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f }; @@ -1187,7 +864,7 @@ static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* o outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f }; @@ -1197,7 +874,7 @@ static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -1207,7 +884,7 @@ static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData[i] = (1.0f - a) * dark[i] + a * light[i]; } -static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) +static void TrackGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData) { static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f }; @@ -1219,11 +896,21 @@ static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { + if (r.isEmpty()) + return; + CGContextRef context = paintInfo.context->platformContext(); paintInfo.context->save(); - int radius = o->style()->borderTopLeftRadius().width(); + IntSize topLeftRadius; + IntSize topRightRadius; + IntSize bottomLeftRadius; + IntSize bottomRightRadius; + + o->style()->getBorderRadiiForRect(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); + + int radius = topLeftRadius.width(); RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); @@ -1246,33 +933,27 @@ void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false)); paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, mainShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, topGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - IntSize(), IntSize()); + paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), topLeftRadius, topRightRadius, IntSize(), IntSize()); CGContextDrawShading(context, topShading.get()); paintInfo.context->restore(); - paintInfo.context->save(); - CGContextClipToRect(context, bottomGradient); - paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), - IntSize(), IntSize(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); - CGContextDrawShading(context, bottomShading.get()); - paintInfo.context->restore(); + if (!bottomGradient.isEmpty()) { + paintInfo.context->save(); + CGContextClipToRect(context, bottomGradient); + paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bottomLeftRadius, bottomRightRadius); + CGContextDrawShading(context, bottomShading.get()); + paintInfo.context->restore(); + } paintInfo.context->save(); CGContextClipToRect(context, r); - paintInfo.context->addRoundedRectClip(r, - o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), - o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); + paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); CGContextDrawShading(context, leftShading.get()); CGContextDrawShading(context, rightShading.get()); paintInfo.context->restore(); @@ -1282,8 +963,6 @@ void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - paintInfo.context->save(); - IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(), r.y() + o->style()->borderTopWidth(), r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(), @@ -1302,6 +981,8 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const RenderOb if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom()) return false; + paintInfo.context->save(); + paintInfo.context->setFillColor(o->style()->color()); paintInfo.context->setStrokeStyle(NoStroke); @@ -1380,7 +1061,7 @@ void RenderThemeChromiumMac::adjustMenuListStyle(CSSStyleSelector* selector, Ren int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[LeftPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[leftPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingLeft * style->effectiveZoom(); return 0; @@ -1389,7 +1070,7 @@ int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[RightPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[rightPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) { float fontScale = style->fontSize() / baseFontSize; float arrowWidth = baseArrowWidth * fontScale; @@ -1401,7 +1082,7 @@ int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[TopPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[topPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingTop * style->effectiveZoom(); return 0; @@ -1410,13 +1091,13 @@ int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const { if (style->appearance() == MenulistPart) - return popupButtonPadding(controlSizeForFont(style))[BottomPadding] * style->effectiveZoom(); + return popupButtonPadding(controlSizeForFont(style))[bottomPadding] * style->effectiveZoom(); if (style->appearance() == MenulistButtonPart) return styledPopupPaddingBottom * style->effectiveZoom(); return 0; } -void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { float fontScale = style->fontSize() / baseFontSize; @@ -1455,16 +1136,16 @@ int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const return sizeForSystemFont(style, menuListSizes()).width(); } -static const int trackWidth = 5; -static const int trackRadius = 2; - -void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { style->setBoxShadow(0); } bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { + static const int trackWidth = 5; + static const int trackRadius = 2; + IntRect bounds = r; float zoomLevel = o->style()->effectiveZoom(); float zoomedTrackWidth = trackWidth * zoomLevel; @@ -1502,12 +1183,12 @@ bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const RenderObjec return false; } -void RenderThemeChromiumMac::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { style->setBoxShadow(0); } -static const float verticalSliderHeightPadding = 0.1f; +const float verticalSliderHeightPadding = 0.1f; bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { @@ -1562,7 +1243,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [sliderThumbCell drawWithFrame:FloatRectToNSRect(unzoomedRect) inView:nil]; + [sliderThumbCell drawWithFrame:unzoomedRect inView:FlippedView()]; [sliderThumbCell setControlView:nil]; paintInfo.context->restore(); @@ -1570,21 +1251,43 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const RenderObjec return false; } -const int sliderThumbWidth = 15; -const int sliderThumbHeight = 15; -const int mediaSliderThumbWidth = 13; -const int mediaSliderThumbHeight = 14; +#if ENABLE(VIDEO) +static Image* mediaSliderThumbImage() +{ + static Image* mediaSliderThumb = Image::loadPlatformResource("mediaSliderThumb").releaseRef(); + return mediaSliderThumb; +} + +static Image* mediaVolumeSliderThumbImage() +{ + static Image* mediaVolumeSliderThumb = Image::loadPlatformResource("mediaVolumeSliderThumb").releaseRef(); + return mediaVolumeSliderThumb; +} +#endif void RenderThemeChromiumMac::adjustSliderThumbSize(RenderObject* o) const { + static const int sliderThumbWidth = 15; + static const int sliderThumbHeight = 15; + float zoomLevel = o->style()->effectiveZoom(); if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) { o->style()->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed)); o->style()->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed)); - } else if (o->style()->appearance() == MediaSliderThumbPart) { - o->style()->setWidth(Length(mediaSliderThumbWidth, Fixed)); - o->style()->setHeight(Length(mediaSliderThumbHeight, Fixed)); } + +#if ENABLE(VIDEO) + Image* thumbImage = 0; + if (o->style()->appearance() == MediaSliderThumbPart) + thumbImage = mediaSliderThumbImage(); + else if (o->style()->appearance() == MediaVolumeSliderThumbPart) + thumbImage = mediaVolumeSliderThumbImage(); + + if (thumbImage) { + o->style()->setWidth(Length(thumbImage->width(), Fixed)); + o->style()->setHeight(Length(thumbImage->height(), Fixed)); + } +#endif } bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) @@ -1611,7 +1314,7 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObjec // Set the search button to nil before drawing. Then reset it so we can draw it later. [search setSearchButtonCell:nil]; - [search drawWithFrame:NSRect(IntRectToNSRect(unzoomedRect)) inView:nil]; + [search drawWithFrame:NSRect(unzoomedRect) inView:FlippedView()]; #ifdef BUILDING_ON_TIGER if ([search showsFirstResponder]) wkDrawTextFieldCellFocusRing(search, NSRect(unzoomedRect)); @@ -1625,7 +1328,7 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const RenderObjec return false; } -void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect& r) +void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&) { NSSearchFieldCell* search = this->search(); @@ -1653,7 +1356,7 @@ void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const setSizeFromFont(style, searchFieldSizes()); } -void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element*) const { // Override border. style->resetBorder(); @@ -1686,9 +1389,10 @@ void RenderThemeChromiumMac::adjustSearchFieldStyle(CSSStyleSelector* selector, bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); @@ -1700,9 +1404,10 @@ bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const float zoomLevel = o->style()->effectiveZoom(); - NSRect bounds = [search cancelButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; - - IntRect unzoomedRect(NSRectToIntRect(bounds)); + FloatRect localBounds = [search cancelButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); + + FloatRect unzoomedRect(localBounds); if (zoomLevel != 1.0f) { unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); @@ -1711,7 +1416,7 @@ bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [[search cancelButtonCell] drawWithFrame:IntRectToNSRect(unzoomedRect) inView:nil]; + [[search cancelButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()]; [[search cancelButtonCell] setControlView:nil]; paintInfo.context->restore(); @@ -1724,7 +1429,7 @@ const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const return sizes; } -void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, cancelButtonSizes()); style->setWidth(Length(size.width(), Fixed)); @@ -1738,8 +1443,8 @@ const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const return sizes; } -static const int emptyResultsOffset = 9; -void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +const int emptyResultsOffset = 9; +void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width() - emptyResultsOffset, Fixed)); @@ -1747,12 +1452,12 @@ void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(CSSStyleSelector* style->setBoxShadow(0); } -bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return false; } -void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width(), Fixed)); @@ -1762,9 +1467,10 @@ void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(CSSStyleSel bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); @@ -1774,14 +1480,16 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, if ([search searchMenuTemplate] != nil) [search setSearchMenuTemplate:nil]; - NSRect bounds = [search searchButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; - [[search searchButtonCell] drawWithFrame:bounds inView:nil]; + FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); + + [[search searchButtonCell] drawWithFrame:localBounds inView:FlippedView()]; [[search searchButtonCell] setControlView:nil]; return false; } -static const int resultsArrowWidth = 5; -void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +const int resultsArrowWidth = 5; +void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { IntSize size = sizeForSystemFont(style, resultsButtonSizes()); style->setWidth(Length(size.width() + resultsArrowWidth, Fixed)); @@ -1791,9 +1499,10 @@ void RenderThemeChromiumMac::adjustSearchFieldResultsButtonStyle(CSSStyleSelecto bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { - LocalCurrentGraphicsContext localContext(paintInfo.context); - Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + setSearchCellState(input->renderer(), r); NSSearchFieldCell* search = this->search(); @@ -1807,9 +1516,10 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons float zoomLevel = o->style()->effectiveZoom(); - NSRect bounds = [search searchButtonRectForBounds:NSRect(IntRectToNSRect(input->renderer()->absoluteBoundingBoxRect()))]; + FloatRect localBounds = [search searchButtonRectForBounds:NSRect(input->renderBox()->borderBoxRect())]; + localBounds = convertToPaintingRect(input->renderer(), o, localBounds, r); - IntRect unzoomedRect(NSRectToIntRect(bounds)); + IntRect unzoomedRect(localBounds); if (zoomLevel != 1.0f) { unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); @@ -1818,7 +1528,7 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); } - [[search searchButtonCell] drawWithFrame:IntRectToNSRect(unzoomedRect) inView:nil]; + [[search searchButtonCell] drawWithFrame:unzoomedRect inView:FlippedView()]; [[search searchButtonCell] setControlView:nil]; paintInfo.context->restore(); @@ -1827,178 +1537,182 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsButton(RenderObject* o, cons } #if ENABLE(VIDEO) -// FIXME: This enum is lifted from RenderThemeMac.mm We need to decide which theme to use for the default controls, or decide to avoid wkDrawMediaUIPart and render our own. -typedef enum { - MediaControllerThemeClassic = 1, - MediaControllerThemeQT = 2 -} MediaControllerThemeStyle; - -enum WKMediaControllerThemeState { - MediaUIPartDisabledFlag = 1 << 0, - MediaUIPartPressedFlag = 1 << 1, - MediaUIPartDrawEndCapsFlag = 1 << 3, -}; -#endif - -bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +// Attempt to retrieve a HTMLMediaElement from a Node. Returns 0 if one cannot be found. +static HTMLMediaElement* mediaElementParent(Node* node) { -#if ENABLE(VIDEO) - Node* node = o->node(); if (!node) - return false; + return 0; + Node* mediaNode = node->shadowAncestorNode(); + if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) + return 0; - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaFullscreenButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return static_cast<HTMLMediaElement*>(mediaNode); } -bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaButtonInternal(GraphicsContext* context, const IntRect& rect, Image* image) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; + // Create a destination rectangle for the image that is centered in the drawing rectangle, rounded left, and down. + IntRect imageRect = image->rect(); + imageRect.setY(rect.y() + (rect.height() - image->height() + 1) / 2); + imageRect.setX(rect.x() + (rect.width() - image->width() + 1) / 2); - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); - if (!mediaElement) - return false; - - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(mediaElement->muted() ? MediaUnMuteButton : MediaMuteButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + context->drawImage(image, imageRect); + return true; } -bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; - - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); + HTMLMediaElement* mediaElement = mediaElementParent(object->node()); if (!mediaElement) return false; - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(mediaElement->canPlay() ? MediaPlayButton : MediaPauseButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + static Image* mediaPlay = Image::loadPlatformResource("mediaPlay").releaseRef(); + static Image* mediaPause = Image::loadPlatformResource("mediaPause").releaseRef(); + static Image* mediaPlayDisabled = Image::loadPlatformResource("mediaPlayDisabled").releaseRef(); + + if (mediaElement->networkState() == HTMLMediaElement::NETWORK_NO_SOURCE) + return paintMediaButtonInternal(paintInfo.context, rect, mediaPlayDisabled); + + return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause); } -bool RenderThemeChromiumMac::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) + HTMLMediaElement* mediaElement = mediaElementParent(object->node()); + if (!mediaElement) return false; - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSeekBackButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + static Image* soundFull = Image::loadPlatformResource("mediaSoundFull").releaseRef(); + static Image* soundNone = Image::loadPlatformResource("mediaSoundNone").releaseRef(); + static Image* soundDisabled = Image::loadPlatformResource("mediaSoundDisabled").releaseRef(); + + if (mediaElement->networkState() == HTMLMediaElement::NETWORK_NO_SOURCE || !mediaElement->hasAudio()) + return paintMediaButtonInternal(paintInfo.context, rect, soundDisabled); + + return paintMediaButtonInternal(paintInfo.context, rect, mediaElement->muted() ? soundNone : soundFull); } -bool RenderThemeChromiumMac::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) + HTMLMediaElement* mediaElement = mediaElementParent(object->node()); + if (!mediaElement) return false; - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSeekForwardButton, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + RenderStyle* style = object->style(); + GraphicsContext* context = paintInfo.context; + context->save(); + + context->setShouldAntialias(true); + + IntSize topLeftRadius = style->borderTopLeftRadius(); + IntSize topRightRadius = style->borderTopRightRadius(); + IntSize bottomLeftRadius = style->borderBottomLeftRadius(); + IntSize bottomRightRadius = style->borderBottomRightRadius(); + float borderWidth = style->borderLeftWidth(); + + // Draw the border of the time bar. + context->setStrokeColor(style->borderLeftColor()); + context->setStrokeThickness(borderWidth); + context->setFillColor(style->backgroundColor()); + context->addPath(Path::createRoundedRectangle(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius)); + context->drawPath(); + + // Draw the buffered ranges. + // FIXME: Draw multiple ranges if there are multiple buffered ranges. + FloatRect bufferedRect = rect; + bufferedRect.inflate(-1.0 - borderWidth); + bufferedRect.setWidth(bufferedRect.width() * mediaElement->percentLoaded()); + bufferedRect = context->roundToDevicePixels(bufferedRect); + + // Don't bother drawing an empty area. + if (bufferedRect.width() > 0 && bufferedRect.height() > 0) { + FloatPoint sliderTopLeft = bufferedRect.location(); + FloatPoint sliderTopRight = sliderTopLeft; + sliderTopRight.move(0.0f, bufferedRect.height()); + + RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); + Color startColor = object->style()->color(); + gradient->addColorStop(0.0, startColor); + gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); + + context->setFillGradient(gradient); + context->addPath(Path::createRoundedRectangle(bufferedRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius)); + context->fillPath(); + } + + context->restore(); + return true; } -bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - Node* mediaNode = node ? node->shadowAncestorNode() : 0; - if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag))) - return false; - - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode); + HTMLMediaElement* mediaElement = mediaElementParent(object->node()); if (!mediaElement) return false; - RefPtr<TimeRanges> timeRanges = mediaElement->buffered(); - ExceptionCode ignoredException; - float timeLoaded = timeRanges->length() ? timeRanges->end(0, ignoredException) : 0; - float currentTime = mediaElement->currentTime(); - float duration = mediaElement->duration(); - if (isnan(duration)) - duration = 0; + GraphicsContext* context = paintInfo.context; + Color originalColor = context->strokeColor(); + if (originalColor != Color::white) + context->setStrokeColor(Color::white); - bool shouldDrawEndCaps = !toRenderMedia(mediaElement->renderer())->shouldShowTimeDisplayControls(); - wkDrawMediaSliderTrack(MediaControllerThemeClassic, paintInfo.context->platformContext(), r, timeLoaded, currentTime, duration, shouldDrawEndCaps ? MediaUIPartDrawEndCapsFlag : 0); -#endif - return false; + int x = rect.x() + rect.width() / 2; + context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height())); + + if (originalColor != Color::white) + context->setStrokeColor(originalColor); + return true; } -bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { -#if ENABLE(VIDEO) - Node* node = o->node(); - if (!node) + if (!object->parent()->isSlider()) return false; - LocalCurrentGraphicsContext localContext(paintInfo.context); - wkDrawMediaUIPart(MediaSliderThumb, MediaControllerThemeClassic, paintInfo.context->platformContext(), r, - node->active() ? MediaUIPartPressedFlag : 0); -#endif - return false; + return paintMediaButtonInternal(paintInfo.context, rect, mediaSliderThumbImage()); } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::checkbox() const +bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { - if (!m_checkbox) { - m_checkbox.adoptNS([[NSButtonCell alloc] init]); - [m_checkbox.get() setButtonType:NSSwitchButton]; - [m_checkbox.get() setTitle:nil]; - [m_checkbox.get() setAllowsMixedState:YES]; - [m_checkbox.get() setFocusRingType:NSFocusRingTypeExterior]; - } - - return m_checkbox.get(); -} + if (!object->parent()->isSlider()) + return false; -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::radio() const -{ - if (!m_radio) { - m_radio.adoptNS([[NSButtonCell alloc] init]); - [m_radio.get() setButtonType:NSRadioButton]; - [m_radio.get() setTitle:nil]; - [m_radio.get() setFocusRingType:NSFocusRingTypeExterior]; - } - - return m_radio.get(); + return paintMediaButtonInternal(paintInfo.context, rect, mediaVolumeSliderThumbImage()); } -// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731. -NSButtonCell* RenderThemeChromiumMac::button() const +bool RenderThemeChromiumMac::paintMediaControlsBackground(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { - if (!m_button) { - m_button.adoptNS([[NSButtonCell alloc] init]); - [m_button.get() setTitle:nil]; - [m_button.get() setButtonType:NSMomentaryPushInButton]; + HTMLMediaElement* mediaElement = mediaElementParent(object->node()); + if (!mediaElement) + return false; + + if (!rect.isEmpty()) + { + GraphicsContext* context = paintInfo.context; + Color originalColor = context->strokeColor(); + + // Draws the left border, it is always 1px wide. + context->setStrokeColor(object->style()->borderLeftColor()); + context->drawLine(IntPoint(rect.x() + 1, rect.y()), + IntPoint(rect.x() + 1, rect.y() + rect.height())); + + + // Draws the right border, it is always 1px wide. + context->setStrokeColor(object->style()->borderRightColor()); + context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()), + IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height())); + + context->setStrokeColor(originalColor); } + return true; +} - return m_button.get(); +String RenderThemeChromiumMac::extraMediaControlsStyleSheet() +{ + return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); } +#endif + NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const { if (!m_popupButton) { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp index e25eed3..82e633b 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumSkia.cpp @@ -640,9 +640,10 @@ void RenderThemeChromiumSkia::adjustSliderThumbSize(RenderObject* object) const else if (object->style()->appearance() == MediaVolumeSliderThumbPart) thumbImage = mediaVolumeSliderThumbImage(); - ASSERT(thumbImage); - object->style()->setWidth(Length(thumbImage->width(), Fixed)); - object->style()->setHeight(Length(thumbImage->height(), Fixed)); + if (thumbImage) { + object->style()->setWidth(Length(thumbImage->width(), Fixed)); + object->style()->setHeight(Length(thumbImage->height(), Fixed)); + } #else UNUSED_PARAM(object); #endif diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp index 169bd02..20503f3 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.cpp @@ -311,6 +311,52 @@ void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescrip fontDescription = *cachedDesc; } +// Map a CSSValue* system color to an index understood by GetSysColor(). +static int cssValueIdToSysColorIndex(int cssValueId) +{ + switch (cssValueId) { + case CSSValueActiveborder: return COLOR_ACTIVEBORDER; + case CSSValueActivecaption: return COLOR_ACTIVECAPTION; + case CSSValueAppworkspace: return COLOR_APPWORKSPACE; + case CSSValueBackground: return COLOR_BACKGROUND; + case CSSValueButtonface: return COLOR_BTNFACE; + case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT; + case CSSValueButtonshadow: return COLOR_BTNSHADOW; + case CSSValueButtontext: return COLOR_BTNTEXT; + case CSSValueCaptiontext: return COLOR_CAPTIONTEXT; + case CSSValueGraytext: return COLOR_GRAYTEXT; + case CSSValueHighlight: return COLOR_HIGHLIGHT; + case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT; + case CSSValueInactiveborder: return COLOR_INACTIVEBORDER; + case CSSValueInactivecaption: return COLOR_INACTIVECAPTION; + case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT; + case CSSValueInfobackground: return COLOR_INFOBK; + case CSSValueInfotext: return COLOR_INFOTEXT; + case CSSValueMenu: return COLOR_MENU; + case CSSValueMenutext: return COLOR_MENUTEXT; + case CSSValueScrollbar: return COLOR_SCROLLBAR; + case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW; + case CSSValueThreedface: return COLOR_3DFACE; + case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT; + case CSSValueThreedlightshadow: return COLOR_3DLIGHT; + case CSSValueThreedshadow: return COLOR_3DSHADOW; + case CSSValueWindow: return COLOR_WINDOW; + case CSSValueWindowframe: return COLOR_WINDOWFRAME; + case CSSValueWindowtext: return COLOR_WINDOWTEXT; + default: return -1; // Unsupported CSSValue + } +} + +Color RenderThemeChromiumWin::systemColor(int cssValueId) const +{ + int sysColorIndex = cssValueIdToSysColorIndex(cssValueId); + if (ChromiumBridge::layoutTestMode() || (sysColorIndex == -1)) + return RenderTheme::systemColor(cssValueId); + + COLORREF color = GetSysColor(sysColorIndex); + return Color(GetRValue(color), GetGValue(color), GetBValue(color)); +} + void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const { // These sizes match what WinXP draws for various menus. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h index 5e98c9b..bbc54a7 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderThemeChromiumWin.h @@ -59,6 +59,7 @@ namespace WebCore { // System fonts. virtual void systemFont(int propId, FontDescription&) const; + virtual Color systemColor(int cssValueId) const; virtual void adjustSliderThumbSize(RenderObject*) const; diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h index 1a216fe..be5d1cf 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyle.h @@ -87,7 +87,11 @@ #include "BindingURI.h" #endif +#ifdef __WINS__ +#define compareEqual(t, u) ((t) == (u)) +#else template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<T>(u); } +#endif #define SET_VAR(group, variable, value) \ if (!compareEqual(group->variable, value)) \ @@ -434,7 +438,6 @@ public: const Font& font() const { return inherited->font; } const FontDescription& fontDescription() const { return inherited->font.fontDescription(); } int fontSize() const { return inherited->font.pixelSize(); } - FontSmoothing fontSmoothing() const { return inherited->font.fontDescription().fontSmoothing(); } const Color& color() const { return inherited->color; } Length textIndent() const { return inherited->indent; } diff --git a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h index 6a7277d..a47defb 100644 --- a/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h +++ b/src/3rdparty/webkit/WebCore/rendering/style/RenderStyleConstants.h @@ -321,10 +321,6 @@ enum EBackfaceVisibility { BackfaceVisibilityVisible, BackfaceVisibilityHidden }; -enum FontSmoothing { - AutoSmoothing, NoSmoothing, Antialiased, SubpixelAntialiased -}; - } // namespace WebCore #endif // RenderStyleConstants_h diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp index 28940a7..dabbac2 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp @@ -207,7 +207,7 @@ void SQLTransaction::performPendingCallback() void SQLTransaction::acquireLock() { - m_database->transactionCoordinator()->acquireLock(this, m_readOnly); + m_database->transactionCoordinator()->acquireLock(this); } void SQLTransaction::lockAcquired() @@ -236,7 +236,7 @@ void SQLTransaction::openTransactionAndPreflight() m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize()); ASSERT(!m_sqliteTransaction); - m_sqliteTransaction.set(new SQLiteTransaction(m_database->m_sqliteDatabase)); + m_sqliteTransaction.set(new SQLiteTransaction(m_database->m_sqliteDatabase, m_readOnly)); m_database->m_databaseAuthorizer->disable(); m_sqliteTransaction->begin(); diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h index 0586cc5..6d6a8d7 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h @@ -79,6 +79,7 @@ public: void performPendingCallback(); Database* database() { return m_database.get(); } + bool isReadOnly() { return m_readOnly; } private: SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp index a42734f..30b0c4a 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp @@ -36,8 +36,8 @@ #include "SQLTransaction.h" #include <wtf/Deque.h> #include <wtf/HashMap.h> +#include <wtf/HashSet.h> #include <wtf/RefPtr.h> -#include <wtf/UnusedParam.h> namespace WebCore { @@ -48,58 +48,67 @@ static String getDatabaseIdentifier(SQLTransaction* transaction) return database->stringIdentifier(); } -void SQLTransactionCoordinator::acquireLock(SQLTransaction* transaction, bool readOnly) +void SQLTransactionCoordinator::processPendingTransactions(CoordinationInfo& info) { - UNUSED_PARAM(readOnly); + if (info.activeWriteTransaction || info.pendingTransactions.isEmpty()) + return; + RefPtr<SQLTransaction> firstPendingTransaction = info.pendingTransactions.first(); + if (firstPendingTransaction->isReadOnly()) { + do { + firstPendingTransaction = info.pendingTransactions.first(); + info.pendingTransactions.removeFirst(); + info.activeReadTransactions.add(firstPendingTransaction); + firstPendingTransaction->lockAcquired(); + } while (!info.pendingTransactions.isEmpty() && info.pendingTransactions.first()->isReadOnly()); + } else if (info.activeReadTransactions.isEmpty()) { + info.pendingTransactions.removeFirst(); + info.activeWriteTransaction = firstPendingTransaction; + firstPendingTransaction->lockAcquired(); + } +} + +void SQLTransactionCoordinator::acquireLock(SQLTransaction* transaction) +{ String dbIdentifier = getDatabaseIdentifier(transaction); - TransactionsHashMap::iterator it = m_pendingTransactions.find(dbIdentifier); - if (it == m_pendingTransactions.end()) { + CoordinationInfoMap::iterator coordinationInfoIterator = m_coordinationInfoMap.find(dbIdentifier); + if (coordinationInfoIterator == m_coordinationInfoMap.end()) { // No pending transactions for this DB - TransactionsQueue pendingTransactions; - pendingTransactions.append(transaction); - m_pendingTransactions.add(dbIdentifier, pendingTransactions); - - // Start the transaction - transaction->lockAcquired(); - } else { - // Another transaction is running on this DB; put this one in the queue - TransactionsQueue& pendingTransactions = it->second; - pendingTransactions.append(transaction); + coordinationInfoIterator = m_coordinationInfoMap.add(dbIdentifier, CoordinationInfo()).first; } + + CoordinationInfo& info = coordinationInfoIterator->second; + info.pendingTransactions.append(transaction); + processPendingTransactions(info); } void SQLTransactionCoordinator::releaseLock(SQLTransaction* transaction) { - if (m_pendingTransactions.isEmpty()) + if (m_coordinationInfoMap.isEmpty()) return; String dbIdentifier = getDatabaseIdentifier(transaction); - TransactionsHashMap::iterator it = m_pendingTransactions.find(dbIdentifier); - ASSERT(it != m_pendingTransactions.end()); - TransactionsQueue& pendingTransactions = it->second; - ASSERT(!pendingTransactions.isEmpty()); + CoordinationInfoMap::iterator coordinationInfoIterator = m_coordinationInfoMap.find(dbIdentifier); + ASSERT(coordinationInfoIterator != m_coordinationInfoMap.end()); + CoordinationInfo& info = coordinationInfoIterator->second; - // 'transaction' should always be the first transaction in this queue - ASSERT(pendingTransactions.first().get() == transaction); - - // Remove 'transaction' from the queue of pending transactions - pendingTransactions.removeFirst(); - if (pendingTransactions.isEmpty()) { - // No more pending transactions; delete dbIdentifier's queue - m_pendingTransactions.remove(it); + if (transaction->isReadOnly()) { + ASSERT(info.activeReadTransactions.contains(transaction)); + info.activeReadTransactions.remove(transaction); } else { - // We have more pending transactions; start the next one - pendingTransactions.first()->lockAcquired(); + ASSERT(info.activeWriteTransaction == transaction); + info.activeWriteTransaction = 0; } + + processPendingTransactions(info); } void SQLTransactionCoordinator::shutdown() { // Clean up all pending transactions for all databases - m_pendingTransactions.clear(); + m_coordinationInfoMap.clear(); } } diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h index 08985cf..20cc863 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h @@ -35,6 +35,7 @@ #include "StringHash.h" #include <wtf/Deque.h> #include <wtf/HashMap.h> +#include <wtf/HashSet.h> #include <wtf/RefPtr.h> namespace WebCore { @@ -43,13 +44,21 @@ namespace WebCore { class SQLTransactionCoordinator { public: - void acquireLock(SQLTransaction*, bool readOnly); + void acquireLock(SQLTransaction*); void releaseLock(SQLTransaction*); void shutdown(); private: typedef Deque<RefPtr<SQLTransaction> > TransactionsQueue; - typedef HashMap<String, TransactionsQueue> TransactionsHashMap; - TransactionsHashMap m_pendingTransactions; + struct CoordinationInfo { + TransactionsQueue pendingTransactions; + HashSet<RefPtr<SQLTransaction> > activeReadTransactions; + RefPtr<SQLTransaction> activeWriteTransaction; + }; + // Maps database names to information about pending transactions + typedef HashMap<String, CoordinationInfo> CoordinationInfoMap; + CoordinationInfoMap m_coordinationInfoMap; + + void processPendingTransactions(CoordinationInfo& info); }; } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp index 5c5d609..2169dd6 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp @@ -190,18 +190,17 @@ bool SVGElement::haveLoadedRequiredResources() return true; } -static bool hasLoadListener(SVGElement* node) +static bool hasLoadListener(Node* node) { - Node* currentNode = node; - while (currentNode && currentNode->isElementNode()) { - const RegisteredEventListenerVector& listeners = static_cast<Element*>(currentNode)->eventListeners(); - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listeners[i]; - if (r.eventType() == eventNames().loadEvent && r.useCapture() || currentNode == node) + if (node->hasEventListeners(eventNames().loadEvent)) + return true; + + for (node = node->parentNode(); node && node->isElementNode(); node = node->parentNode()) { + const EventListenerVector& entry = node->getEventListeners(eventNames().loadEvent); + for (size_t i = 0; i < entry.size(); ++i) { + if (entry[i].useCapture) return true; } - currentNode = currentNode->parentNode(); } return false; @@ -219,7 +218,7 @@ void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents) event->setTarget(currentTarget); currentTarget->dispatchGenericEvent(event.release()); } - currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : 0; + currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : RefPtr<SVGElement> (0); } } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp b/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp index 3a82067..46e8221 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp @@ -43,6 +43,13 @@ namespace WebCore { static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance"); #endif +static EventTargetData& dummyEventTargetData() +{ + DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ()); + dummyEventTargetData.eventListenerMap.clear(); + return dummyEventTargetData; +} + SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement) : m_needsUpdate(false) , m_useElement(useElement) @@ -137,438 +144,52 @@ ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const return 0; } -void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) -{ - if (SVGElement* element = correspondingElement()) - element->addEventListener(eventType, listener, useCapture); -} - -void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) -{ - if (SVGElement* element = correspondingElement()) - element->removeEventListener(eventType, listener, useCapture); -} - -bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) +bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - RefPtr<Event> evt(e); - ASSERT(!eventDispatchForbidden()); - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return false; - } - - // The event has to be dispatched to the shadowTreeElement(), not the correspondingElement()! - SVGElement* element = shadowTreeElement(); - if (!element) + if (!correspondingElement()) return false; - - evt->setTarget(this); - - RefPtr<FrameView> view = element->document()->view(); - return element->dispatchGenericEvent(evt.release()); -} - -EventListener* SVGElementInstance::onabort() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().abortEvent); -} - -void SVGElementInstance::setOnabort(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().abortEvent, eventListener); -} - -EventListener* SVGElementInstance::onblur() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().blurEvent); -} - -void SVGElementInstance::setOnblur(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* SVGElementInstance::onchange() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().changeEvent); -} - -void SVGElementInstance::setOnchange(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().changeEvent, eventListener); -} - -EventListener* SVGElementInstance::onclick() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().clickEvent); -} - -void SVGElementInstance::setOnclick(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().clickEvent, eventListener); -} - -EventListener* SVGElementInstance::oncontextmenu() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().contextmenuEvent); -} - -void SVGElementInstance::setOncontextmenu(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().contextmenuEvent, eventListener); -} - -EventListener* SVGElementInstance::ondblclick() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dblclickEvent); -} - -void SVGElementInstance::setOndblclick(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dblclickEvent, eventListener); -} - -EventListener* SVGElementInstance::onerror() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().errorEvent); -} - -void SVGElementInstance::setOnerror(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* SVGElementInstance::onfocus() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().focusEvent); -} - -void SVGElementInstance::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* SVGElementInstance::oninput() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().inputEvent); -} - -void SVGElementInstance::setOninput(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().inputEvent, eventListener); -} - -EventListener* SVGElementInstance::onkeydown() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().keydownEvent); -} - -void SVGElementInstance::setOnkeydown(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().keydownEvent, eventListener); -} - -EventListener* SVGElementInstance::onkeypress() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().keypressEvent); -} - -void SVGElementInstance::setOnkeypress(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().keypressEvent, eventListener); -} - -EventListener* SVGElementInstance::onkeyup() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().keyupEvent); -} - -void SVGElementInstance::setOnkeyup(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().keyupEvent, eventListener); -} - -EventListener* SVGElementInstance::onload() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().loadEvent); + return correspondingElement()->addEventListener(eventType, listener, useCapture); } -void SVGElementInstance::setOnload(PassRefPtr<EventListener> eventListener) +bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - correspondingElement()->setAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* SVGElementInstance::onmousedown() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mousedownEvent); -} - -void SVGElementInstance::setOnmousedown(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mousedownEvent, eventListener); -} - -EventListener* SVGElementInstance::onmousemove() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mousemoveEvent); -} - -void SVGElementInstance::setOnmousemove(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mousemoveEvent, eventListener); -} - -EventListener* SVGElementInstance::onmouseout() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mouseoutEvent); -} - -void SVGElementInstance::setOnmouseout(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mouseoutEvent, eventListener); -} - -EventListener* SVGElementInstance::onmouseover() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mouseoverEvent); -} - -void SVGElementInstance::setOnmouseover(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mouseoverEvent, eventListener); -} - -EventListener* SVGElementInstance::onmouseup() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mouseupEvent); -} - -void SVGElementInstance::setOnmouseup(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mouseupEvent, eventListener); -} - -EventListener* SVGElementInstance::onmousewheel() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().mousewheelEvent); -} - -void SVGElementInstance::setOnmousewheel(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().mousewheelEvent, eventListener); -} - -EventListener* SVGElementInstance::onbeforecut() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().beforecutEvent); -} - -void SVGElementInstance::setOnbeforecut(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().beforecutEvent, eventListener); -} - -EventListener* SVGElementInstance::oncut() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().cutEvent); -} - -void SVGElementInstance::setOncut(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().cutEvent, eventListener); -} - -EventListener* SVGElementInstance::onbeforecopy() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().beforecopyEvent); -} - -void SVGElementInstance::setOnbeforecopy(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().beforecopyEvent, eventListener); -} - -EventListener* SVGElementInstance::oncopy() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().copyEvent); -} - -void SVGElementInstance::setOncopy(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().copyEvent, eventListener); -} - -EventListener* SVGElementInstance::onbeforepaste() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().beforepasteEvent); -} - -void SVGElementInstance::setOnbeforepaste(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().beforepasteEvent, eventListener); -} - -EventListener* SVGElementInstance::onpaste() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().pasteEvent); -} - -void SVGElementInstance::setOnpaste(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().pasteEvent, eventListener); -} - -EventListener* SVGElementInstance::ondragenter() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragenterEvent); -} - -void SVGElementInstance::setOndragenter(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragenterEvent, eventListener); -} - -EventListener* SVGElementInstance::ondragover() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragoverEvent); -} - -void SVGElementInstance::setOndragover(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragoverEvent, eventListener); -} - -EventListener* SVGElementInstance::ondragleave() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragleaveEvent); -} - -void SVGElementInstance::setOndragleave(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragleaveEvent, eventListener); -} - -EventListener* SVGElementInstance::ondrop() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dropEvent); -} - -void SVGElementInstance::setOndrop(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dropEvent, eventListener); -} - -EventListener* SVGElementInstance::ondragstart() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragstartEvent); -} - -void SVGElementInstance::setOndragstart(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragstartEvent, eventListener); -} - -EventListener* SVGElementInstance::ondrag() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragEvent); -} - -void SVGElementInstance::setOndrag(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragEvent, eventListener); -} - -EventListener* SVGElementInstance::ondragend() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().dragendEvent); -} - -void SVGElementInstance::setOndragend(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().dragendEvent, eventListener); -} - -EventListener* SVGElementInstance::onreset() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().resetEvent); -} - -void SVGElementInstance::setOnreset(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().resetEvent, eventListener); -} - -EventListener* SVGElementInstance::onresize() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().resizeEvent); -} - -void SVGElementInstance::setOnresize(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().resizeEvent, eventListener); -} - -EventListener* SVGElementInstance::onscroll() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().scrollEvent); -} - -void SVGElementInstance::setOnscroll(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().scrollEvent, eventListener); -} - -EventListener* SVGElementInstance::onsearch() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().searchEvent); -} - -void SVGElementInstance::setOnsearch(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().searchEvent, eventListener); -} - -EventListener* SVGElementInstance::onselect() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().selectEvent); + if (!correspondingElement()) + return false; + return correspondingElement()->removeEventListener(eventType, listener, useCapture); } -void SVGElementInstance::setOnselect(PassRefPtr<EventListener> eventListener) +void SVGElementInstance::removeAllEventListeners() { - correspondingElement()->setAttributeEventListener(eventNames().selectEvent, eventListener); + if (!correspondingElement()) + return; + correspondingElement()->removeAllEventListeners(); } -EventListener* SVGElementInstance::onselectstart() const +bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent) { - return correspondingElement()->getAttributeEventListener(eventNames().selectstartEvent); -} + RefPtr<EventTarget> protect = this; + RefPtr<Event> event = prpEvent; -void SVGElementInstance::setOnselectstart(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().selectstartEvent, eventListener); -} + event->setTarget(this); -EventListener* SVGElementInstance::onsubmit() const -{ - return correspondingElement()->getAttributeEventListener(eventNames().submitEvent); -} + SVGElement* element = shadowTreeElement(); + if (!element) + return false; -void SVGElementInstance::setOnsubmit(PassRefPtr<EventListener> eventListener) -{ - correspondingElement()->setAttributeEventListener(eventNames().submitEvent, eventListener); + RefPtr<FrameView> view = element->document()->view(); + return element->dispatchGenericEvent(event.release()); } -EventListener* SVGElementInstance::onunload() const +EventTargetData* SVGElementInstance::eventTargetData() { - return correspondingElement()->getAttributeEventListener(eventNames().unloadEvent); + return correspondingElement() ? correspondingElement()->eventTargetData() : 0; } -void SVGElementInstance::setOnunload(PassRefPtr<EventListener> eventListener) +EventTargetData* SVGElementInstance::ensureEventTargetData() { - correspondingElement()->setAttributeEventListener(eventNames().unloadEvent, eventListener); + return &dummyEventTargetData(); // return something, so we don't crash } -} +} // namespace WebCore #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h b/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h index 048c66c..3cdc761 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h +++ b/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h @@ -51,10 +51,11 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const; - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - const RegisteredEventListenerVector& eventListeners() const { return correspondingElement()->eventListeners(); } + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual void removeAllEventListeners(); + using EventTarget::dispatchEvent; + virtual bool dispatchEvent(PassRefPtr<Event>); SVGElement* correspondingElement() const { return m_element.get(); } SVGUseElement* correspondingUseElement() const { return m_useElement; } @@ -77,86 +78,46 @@ namespace WebCore { using TreeShared<SVGElementInstance>::deref; // EventTarget API - EventListener* onabort() const; - void setOnabort(PassRefPtr<EventListener>); - EventListener* onblur() const; - void setOnblur(PassRefPtr<EventListener>); - EventListener* onchange() const; - void setOnchange(PassRefPtr<EventListener>); - EventListener* onclick() const; - void setOnclick(PassRefPtr<EventListener>); - EventListener* oncontextmenu() const; - void setOncontextmenu(PassRefPtr<EventListener>); - EventListener* ondblclick() const; - void setOndblclick(PassRefPtr<EventListener>); - EventListener* onerror() const; - void setOnerror(PassRefPtr<EventListener>); - EventListener* onfocus() const; - void setOnfocus(PassRefPtr<EventListener>); - EventListener* oninput() const; - void setOninput(PassRefPtr<EventListener>); - EventListener* onkeydown() const; - void setOnkeydown(PassRefPtr<EventListener>); - EventListener* onkeypress() const; - void setOnkeypress(PassRefPtr<EventListener>); - EventListener* onkeyup() const; - void setOnkeyup(PassRefPtr<EventListener>); - EventListener* onload() const; - void setOnload(PassRefPtr<EventListener>); - EventListener* onmousedown() const; - void setOnmousedown(PassRefPtr<EventListener>); - EventListener* onmousemove() const; - void setOnmousemove(PassRefPtr<EventListener>); - EventListener* onmouseout() const; - void setOnmouseout(PassRefPtr<EventListener>); - EventListener* onmouseover() const; - void setOnmouseover(PassRefPtr<EventListener>); - EventListener* onmouseup() const; - void setOnmouseup(PassRefPtr<EventListener>); - EventListener* onmousewheel() const; - void setOnmousewheel(PassRefPtr<EventListener>); - EventListener* onbeforecut() const; - void setOnbeforecut(PassRefPtr<EventListener>); - EventListener* oncut() const; - void setOncut(PassRefPtr<EventListener>); - EventListener* onbeforecopy() const; - void setOnbeforecopy(PassRefPtr<EventListener>); - EventListener* oncopy() const; - void setOncopy(PassRefPtr<EventListener>); - EventListener* onbeforepaste() const; - void setOnbeforepaste(PassRefPtr<EventListener>); - EventListener* onpaste() const; - void setOnpaste(PassRefPtr<EventListener>); - EventListener* ondragenter() const; - void setOndragenter(PassRefPtr<EventListener>); - EventListener* ondragover() const; - void setOndragover(PassRefPtr<EventListener>); - EventListener* ondragleave() const; - void setOndragleave(PassRefPtr<EventListener>); - EventListener* ondrop() const; - void setOndrop(PassRefPtr<EventListener>); - EventListener* ondragstart() const; - void setOndragstart(PassRefPtr<EventListener>); - EventListener* ondrag() const; - void setOndrag(PassRefPtr<EventListener>); - EventListener* ondragend() const; - void setOndragend(PassRefPtr<EventListener>); - EventListener* onreset() const; - void setOnreset(PassRefPtr<EventListener>); - EventListener* onresize() const; - void setOnresize(PassRefPtr<EventListener>); - EventListener* onscroll() const; - void setOnscroll(PassRefPtr<EventListener>); - EventListener* onsearch() const; - void setOnsearch(PassRefPtr<EventListener>); - EventListener* onselect() const; - void setOnselect(PassRefPtr<EventListener>); - EventListener* onselectstart() const; - void setOnselectstart(PassRefPtr<EventListener>); - EventListener* onsubmit() const; - void setOnsubmit(PassRefPtr<EventListener>); - EventListener* onunload() const; - void setOnunload(PassRefPtr<EventListener>); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit); + DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload); private: friend class SVGUseElement; @@ -189,6 +150,8 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); bool m_needsUpdate : 1; diff --git a/src/3rdparty/webkit/WebCore/svg/SVGImageLoader.cpp b/src/3rdparty/webkit/WebCore/svg/SVGImageLoader.cpp index f8380f5..5d5d3bc 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGImageLoader.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGImageLoader.cpp @@ -25,6 +25,7 @@ #if ENABLE(SVG) #include "SVGImageLoader.h" +#include "Event.h" #include "EventNames.h" #include "SVGImageElement.h" #include "RenderImage.h" @@ -43,7 +44,7 @@ SVGImageLoader::~SVGImageLoader() void SVGImageLoader::dispatchLoadEvent() { if (image()->errorOccurred()) - element()->dispatchEvent(eventNames().errorEvent, false, false); + element()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); else { SVGImageElement* imageElement = static_cast<SVGImageElement*>(element()); if (imageElement->externalResourcesRequiredBaseValue()) diff --git a/src/3rdparty/webkit/WebCore/svg/SVGScriptElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGScriptElement.cpp index 2ecf912..587542c 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGScriptElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGScriptElement.cpp @@ -26,6 +26,7 @@ #include "SVGScriptElement.h" #include "Document.h" +#include "Event.h" #include "EventNames.h" #include "MappedAttribute.h" #include "SVGNames.h" @@ -209,7 +210,7 @@ void SVGScriptElement::dispatchLoadEvent() void SVGScriptElement::dispatchErrorEvent() { - dispatchEvent(eventNames().errorEvent, true, false); + dispatchEvent(Event::create(eventNames().errorEvent, true, false)); } } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp index 9cb3024..4b66e03 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp @@ -768,18 +768,18 @@ void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* targe ASSERT(originalElement); if (SVGElement* shadowTreeElement = target->shadowTreeElement()) { - const RegisteredEventListenerVector& listeners = originalElement->eventListeners(); - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listeners[i]; - EventListener* listener = r.listener(); - ASSERT(listener); - - // Event listeners created from markup have already been transfered to the shadow tree during cloning! - if (listener->wasCreatedFromMarkup()) - continue; - - shadowTreeElement->addEventListener(r.eventType(), listener, r.useCapture()); + if (EventTargetData* d = originalElement->eventTargetData()) { + EventListenerMap& map = d->eventListenerMap; + EventListenerMap::iterator end = map.end(); + for (EventListenerMap::iterator it = map.begin(); it != end; ++it) { + EventListenerVector& entry = it->second; + for (size_t i = 0; i < entry.size(); ++i) { + // Event listeners created from markup have already been transfered to the shadow tree during cloning. + if (entry[i].listener->wasCreatedFromMarkup()) + continue; + shadowTreeElement->addEventListener(it->first, entry[i].listener, entry[i].useCapture); + } + } } } diff --git a/src/3rdparty/webkit/WebCore/svg/animation/SVGSMILElement.cpp b/src/3rdparty/webkit/WebCore/svg/animation/SVGSMILElement.cpp index 982afd5..8ec9435 100644 --- a/src/3rdparty/webkit/WebCore/svg/animation/SVGSMILElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/animation/SVGSMILElement.cpp @@ -87,7 +87,7 @@ private: m_eventBase->addEventListener(m_condition->m_name, this, false); } - virtual void handleEvent(Event*, bool); + virtual void handleEvent(Event*); SVGSMILElement* m_animation; SVGSMILElement::Condition* m_condition; @@ -103,7 +103,7 @@ bool ConditionEventListener::operator==(const EventListener& listener) return false; } -void ConditionEventListener::handleEvent(Event* event, bool) +void ConditionEventListener::handleEvent(Event* event) { m_animation->handleConditionEvent(event, m_condition); } diff --git a/src/3rdparty/webkit/WebCore/websockets/WebSocket.cpp b/src/3rdparty/webkit/WebCore/websockets/WebSocket.cpp index 8f90b1c..dd89c14 100644 --- a/src/3rdparty/webkit/WebCore/websockets/WebSocket.cpp +++ b/src/3rdparty/webkit/WebCore/websockets/WebSocket.cpp @@ -52,23 +52,23 @@ namespace WebCore { class ProcessWebSocketEventTask : public ScriptExecutionContext::Task { public: typedef void (WebSocket::*Method)(Event*); - static PassRefPtr<ProcessWebSocketEventTask> create(PassRefPtr<WebSocket> webSocket, Method method, PassRefPtr<Event> event) + static PassRefPtr<ProcessWebSocketEventTask> create(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event) { - return adoptRef(new ProcessWebSocketEventTask(webSocket, method, event)); + return adoptRef(new ProcessWebSocketEventTask(webSocket, event)); } virtual void performTask(ScriptExecutionContext*) { - (m_webSocket.get()->*m_method)(m_event.get()); + ExceptionCode ec = 0; + m_webSocket->dispatchEvent(m_event.get(), ec); + ASSERT(!ec); } private: - ProcessWebSocketEventTask(PassRefPtr<WebSocket> webSocket, Method method, PassRefPtr<Event> event) + ProcessWebSocketEventTask(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event) : m_webSocket(webSocket) - , m_method(method) , m_event(event) { } RefPtr<WebSocket> m_webSocket; - Method m_method; RefPtr<Event> m_event; }; @@ -171,54 +171,6 @@ ScriptExecutionContext* WebSocket::scriptExecutionContext() const return ActiveDOMObject::scriptExecutionContext(); } -void WebSocket::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) - if (*listenerIter == eventListener) - return; - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void WebSocket::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) - if (*listenerIter == eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } -} - -bool WebSocket::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec) -{ - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(evt->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - evt->setTarget(this); - evt->setCurrentTarget(this); - listenerIter->get()->handleEvent(evt.get(), false); - } - return !evt->defaultPrevented(); -} - void WebSocket::didConnect() { LOG(Network, "WebSocket %p didConnect", this); @@ -227,7 +179,7 @@ void WebSocket::didConnect() return; } m_state = OPEN; - scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchOpenEvent, Event::create(eventNames().openEvent, false, false))); + scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().openEvent, false, false))); } void WebSocket::didReceiveMessage(const String& msg) @@ -238,53 +190,24 @@ void WebSocket::didReceiveMessage(const String& msg) RefPtr<MessageEvent> evt = MessageEvent::create(); // FIXME: origin, lastEventId, source, messagePort. evt->initMessageEvent(eventNames().messageEvent, false, false, msg, "", "", 0, 0); - scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchMessageEvent, evt)); + scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, evt)); } void WebSocket::didClose() { LOG(Network, "WebSocket %p didClose", this); m_state = CLOSED; - scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchCloseEvent, Event::create(eventNames().closeEvent, false, false))); + scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().closeEvent, false, false))); } -void WebSocket::dispatchOpenEvent(Event* evt) +EventTargetData* WebSocket::eventTargetData() { - if (m_onopen) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onopen->handleEvent(evt, false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt, ec); - ASSERT(!ec); + return &m_eventTargetData; } -void WebSocket::dispatchMessageEvent(Event* evt) +EventTargetData* WebSocket::ensureEventTargetData() { - if (m_onmessage) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onmessage->handleEvent(evt, false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt, ec); - ASSERT(!ec); -} - -void WebSocket::dispatchCloseEvent(Event* evt) -{ - if (m_onclose) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onclose->handleEvent(evt, false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt, ec); - ASSERT(!ec); + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/websockets/WebSocket.h b/src/3rdparty/webkit/WebCore/websockets/WebSocket.h index 2be3445..c5b7ee7 100644 --- a/src/3rdparty/webkit/WebCore/websockets/WebSocket.h +++ b/src/3rdparty/webkit/WebCore/websockets/WebSocket.h @@ -36,6 +36,7 @@ #include "ActiveDOMObject.h" #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "KURL.h" #include "WebSocketChannelClient.h" @@ -69,26 +70,15 @@ namespace WebCore { State readyState() const; unsigned long bufferedAmount() const; - void setOnopen(PassRefPtr<EventListener> eventListener) { m_onopen = eventListener; } - EventListener* onopen() const { return m_onopen.get(); } - void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onmessage = eventListener; } - EventListener* onmessage() const { return m_onmessage.get(); } - void setOnclose(PassRefPtr<EventListener> eventListener) { m_onclose = eventListener; } - EventListener* onclose() const { return m_onclose.get(); } + DEFINE_ATTRIBUTE_EVENT_LISTENER(open); + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); + DEFINE_ATTRIBUTE_EVENT_LISTENER(close); // EventTarget virtual WebSocket* toWebSocket() { return this; } virtual ScriptExecutionContext* scriptExecutionContext() const; - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - EventListenersMap& eventListeners() { return m_eventListeners; } - // ActiveDOMObject // virtual bool hasPendingActivity() const; // virtual void contextDestroyed(); @@ -110,6 +100,8 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); void dispatchOpenEvent(Event*); void dispatchMessageEvent(Event*); @@ -117,14 +109,10 @@ namespace WebCore { RefPtr<WebSocketChannel> m_channel; - RefPtr<EventListener> m_onopen; - RefPtr<EventListener> m_onmessage; - RefPtr<EventListener> m_onclose; - EventListenersMap m_eventListeners; - State m_state; KURL m_url; String m_protocol; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/websockets/WebSocket.idl b/src/3rdparty/webkit/WebCore/websockets/WebSocket.idl index cdb916f..04606fe 100644 --- a/src/3rdparty/webkit/WebCore/websockets/WebSocket.idl +++ b/src/3rdparty/webkit/WebCore/websockets/WebSocket.idl @@ -31,9 +31,9 @@ module websockets { interface [ - CustomMarkFunction, - NoStaticTables, - Conditional=WEB_SOCKETS + Conditional=WEB_SOCKETS, + EventTarget, + NoStaticTables ] WebSocket { readonly attribute DOMString URL; diff --git a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.cpp b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.cpp index d28b011..6ba8922 100644 --- a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.cpp +++ b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.cpp @@ -52,90 +52,6 @@ AbstractWorker::~AbstractWorker() { } -void AbstractWorker::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void AbstractWorker::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool AbstractWorker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - -void AbstractWorker::dispatchLoadErrorEvent() -{ - RefPtr<Event> evt = Event::create(eventNames().errorEvent, false, true); - if (m_onErrorListener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onErrorListener->handleEvent(evt.get(), true); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - -bool AbstractWorker::dispatchScriptErrorEvent(const String& message, const String& sourceURL, int lineNumber) -{ - bool handled = false; - RefPtr<ErrorEvent> event = ErrorEvent::create(message, sourceURL, static_cast<unsigned>(lineNumber)); - if (m_onErrorListener) { - event->setTarget(this); - event->setCurrentTarget(this); - m_onErrorListener->handleEvent(event.get(), true); - if (event->defaultPrevented()) - handled = true; - } - - ExceptionCode ec = 0; - handled = !dispatchEvent(event.release(), ec); - ASSERT(!ec); - - return handled; -} - KURL AbstractWorker::resolveURL(const String& url, ExceptionCode& ec) { if (url.isEmpty()) { @@ -157,6 +73,16 @@ KURL AbstractWorker::resolveURL(const String& url, ExceptionCode& ec) return scriptURL; } +EventTargetData* AbstractWorker::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* AbstractWorker::ensureEventTargetData() +{ + return &m_eventTargetData; +} + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.h b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.h index a882542..2209856 100644 --- a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.h +++ b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.h @@ -36,6 +36,7 @@ #include "ActiveDOMObject.h" #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -51,19 +52,7 @@ namespace WebCore { // EventTarget APIs virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); } - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - - // Utility routines to generate appropriate error events for loading and script exceptions. - void dispatchLoadErrorEvent(); - bool dispatchScriptErrorEvent(const String& errorMessage, const String& sourceURL, int); - - void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; } - EventListener* onerror() const { return m_onErrorListener.get(); } - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); using RefCounted<AbstractWorker>::ref; using RefCounted<AbstractWorker>::deref; @@ -78,9 +67,10 @@ namespace WebCore { private: virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } - - RefPtr<EventListener> m_onErrorListener; - EventListenersMap m_eventListeners; + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); + + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.idl b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.idl index ae7ebc6..00b8fbb 100644 --- a/src/3rdparty/webkit/WebCore/workers/AbstractWorker.idl +++ b/src/3rdparty/webkit/WebCore/workers/AbstractWorker.idl @@ -32,8 +32,8 @@ module threads { interface [ Conditional=WORKERS, - CustomMarkFunction, CustomToJS, + EventTarget, GenerateConstructor ] AbstractWorker { diff --git a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.cpp b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.cpp index 8c5ee47..5206fd9 100644 --- a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.cpp +++ b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.cpp @@ -71,23 +71,6 @@ void DedicatedWorkerContext::postMessage(const String& message, const MessagePor thread()->workerObjectProxy().postMessageToWorkerObject(message, channels.release()); } -void DedicatedWorkerContext::dispatchMessage(const String& message, PassOwnPtr<MessagePortArray> ports) -{ - // Since close() stops the thread event loop, this should not ever get called while closing. - ASSERT(!isClosing()); - RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, ports); - - if (m_onmessageListener.get()) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onmessageListener->handleEvent(evt.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - void DedicatedWorkerContext::importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode& ec) { Base::importScripts(urls, callerURL, callerLine, ec); diff --git a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.h b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.h index 3bc4aee..7609fcd 100644 --- a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.h +++ b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.h @@ -59,15 +59,12 @@ namespace WebCore { void postMessage(const String&, const MessagePortArray*, ExceptionCode&); // FIXME: remove this when we update the ObjC bindings (bug #28774). void postMessage(const String&, MessagePort*, ExceptionCode&); - void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onmessageListener = eventListener; } - EventListener* onmessage() const { return m_onmessageListener.get(); } - void dispatchMessage(const String&, PassOwnPtr<MessagePortArray>); + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); DedicatedWorkerThread* thread(); private: DedicatedWorkerContext(const KURL&, const String&, DedicatedWorkerThread*); - RefPtr<EventListener> m_onmessageListener; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.idl b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.idl index ef3ebfe..899bbae 100644 --- a/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.idl +++ b/src/3rdparty/webkit/WebCore/workers/DedicatedWorkerContext.idl @@ -32,7 +32,6 @@ module threads { interface [ Conditional=WORKERS, - CustomMarkFunction, ExtendsDOMGlobalObject, IsWorkerContext, GenerateNativeConverter, diff --git a/src/3rdparty/webkit/WebCore/workers/DefaultSharedWorkerRepository.cpp b/src/3rdparty/webkit/WebCore/workers/DefaultSharedWorkerRepository.cpp index e955f24..11106ee 100644 --- a/src/3rdparty/webkit/WebCore/workers/DefaultSharedWorkerRepository.cpp +++ b/src/3rdparty/webkit/WebCore/workers/DefaultSharedWorkerRepository.cpp @@ -37,6 +37,7 @@ #include "ActiveDOMObject.h" #include "Document.h" #include "GenericWorkerTask.h" +#include "MessageEvent.h" #include "MessagePort.h" #include "NotImplemented.h" #include "PlatformString.h" @@ -64,7 +65,7 @@ public: bool isClosing() const { return m_closing; } KURL url() const { return m_url.copy(); } String name() const { return m_name.copy(); } - bool matches(const String& name, PassRefPtr<SecurityOrigin> origin) const { return name == m_name && origin->equal(m_origin.get()); } + bool matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const; // WorkerLoaderProxy virtual void postTaskToLoader(PassRefPtr<ScriptExecutionContext::Task>); @@ -109,6 +110,19 @@ SharedWorkerProxy::SharedWorkerProxy(const String& name, const KURL& url, PassRe ASSERT(m_origin->hasOneRef()); } +bool SharedWorkerProxy::matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const +{ + // If the origins don't match, or the names don't match, then this is not the proxy we are looking for. + if (!origin->equal(m_origin.get())) + return false; + + // If the names are both empty, compares the URLs instead per the Web Workers spec. + if (name.isEmpty() && m_name.isEmpty()) + return urlToMatch == url(); + + return name == m_name; +} + void SharedWorkerProxy::postTaskToLoader(PassRefPtr<ScriptExecutionContext::Task> task) { MutexLocker lock(m_workerDocumentsLock); @@ -219,8 +233,10 @@ private: port->entangle(m_channel.release()); ASSERT(scriptContext->isWorkerContext()); WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext); + // Since close() stops the thread event loop, this should not ever get called while closing. + ASSERT(!workerContext->isClosing()); ASSERT(workerContext->isSharedWorkerContext()); - workerContext->toSharedWorkerContext()->dispatchConnect(port); + workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port)); } OwnPtr<MessagePortChannel> m_channel; @@ -259,18 +275,19 @@ void SharedWorkerScriptLoader::load(const KURL& url) // Stay alive until the load finishes. setPendingActivity(this); + m_worker->setPendingActivity(m_worker.get()); } void SharedWorkerScriptLoader::notifyFinished() { // Hand off the just-loaded code to the repository to start up the worker thread. if (m_scriptLoader->failed()) - m_worker->dispatchLoadErrorEvent(); + m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); else DefaultSharedWorkerRepository::instance().workerScriptLoaded(*m_proxy, scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), m_port.release()); - // This frees this object - must be the last action in this function. - unsetPendingActivity(this); + m_worker->unsetPendingActivity(m_worker.get()); + unsetPendingActivity(this); // This frees this object - must be the last action in this function. } DefaultSharedWorkerRepository& DefaultSharedWorkerRepository::instance() @@ -365,7 +382,7 @@ PassRefPtr<SharedWorkerProxy> DefaultSharedWorkerRepository::getProxy(const Stri // Items in the cache are freed on another thread, so copy the URL before creating the origin, to make sure no references to external strings linger. RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url.copy()); for (unsigned i = 0; i < m_proxies.size(); i++) { - if (!m_proxies[i]->isClosing() && m_proxies[i]->matches(name, origin)) + if (!m_proxies[i]->isClosing() && m_proxies[i]->matches(name, origin, url)) return m_proxies[i]; } // Proxy is not in the repository currently - create a new one. diff --git a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.cpp b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.cpp index bebcc73..cd76e3b 100644 --- a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.cpp +++ b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.cpp @@ -42,6 +42,13 @@ namespace WebCore { +PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> port) +{ + RefPtr<MessageEvent> event = MessageEvent::create(new MessagePortArray(1, port)); + event->initEvent(eventNames().connectEvent, false, false); + return event; +} + SharedWorkerContext::SharedWorkerContext(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread) : WorkerContext(url, userAgent, thread) , m_name(name) @@ -52,27 +59,6 @@ SharedWorkerContext::~SharedWorkerContext() { } -void SharedWorkerContext::dispatchConnect(PassRefPtr<MessagePort> port) -{ - // Since close() stops the thread event loop, this should not ever get called while closing. - ASSERT(!isClosing()); - // The connect event uses the MessageEvent interface, but has the name "connect". - OwnPtr<MessagePortArray> portArray(new MessagePortArray()); - portArray->append(port); - RefPtr<Event> event = MessageEvent::create("", "", "", 0, portArray.release()); - event->initEvent(eventNames().connectEvent, false, false); - - if (m_onconnectListener.get()) { - event->setTarget(this); - event->setCurrentTarget(this); - m_onconnectListener->handleEvent(event.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - SharedWorkerThread* SharedWorkerContext::thread() { return static_cast<SharedWorkerThread*>(Base::thread()); diff --git a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.h b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.h index d6956cd..59a7605 100644 --- a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.h +++ b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.h @@ -37,6 +37,7 @@ namespace WebCore { + class MessageEvent; class SharedWorkerThread; class SharedWorkerContext : public WorkerContext { @@ -54,19 +55,17 @@ namespace WebCore { virtual SharedWorkerContext* toSharedWorkerContext() { return this; } // Setters/Getters for attributes in SharedWorkerContext.idl - void setOnconnect(PassRefPtr<EventListener> eventListener) { m_onconnectListener = eventListener; } - EventListener* onconnect() const { return m_onconnectListener.get(); } + DEFINE_ATTRIBUTE_EVENT_LISTENER(connect); String name() const { return m_name; } - void dispatchConnect(PassRefPtr<MessagePort>); - SharedWorkerThread* thread(); private: SharedWorkerContext(const String& name, const KURL&, const String&, SharedWorkerThread*); - RefPtr<EventListener> m_onconnectListener; String m_name; }; + PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort>); + } // namespace WebCore #endif // ENABLE(SHARED_WORKERS) diff --git a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.idl b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.idl index 8e450e0..a48e5bd 100644 --- a/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.idl +++ b/src/3rdparty/webkit/WebCore/workers/SharedWorkerContext.idl @@ -32,7 +32,6 @@ module threads { interface [ Conditional=SHARED_WORKERS, - CustomMarkFunction, ExtendsDOMGlobalObject, IsWorkerContext, GenerateNativeConverter, diff --git a/src/3rdparty/webkit/WebCore/workers/Worker.cpp b/src/3rdparty/webkit/WebCore/workers/Worker.cpp index 922cd33..c2c25c1 100644 --- a/src/3rdparty/webkit/WebCore/workers/Worker.cpp +++ b/src/3rdparty/webkit/WebCore/workers/Worker.cpp @@ -116,7 +116,7 @@ bool Worker::hasPendingActivity() const void Worker::notifyFinished() { if (m_scriptLoader->failed()) - dispatchLoadErrorEvent(); + dispatchEvent(Event::create(eventNames().errorEvent, false, true)); else m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script()); @@ -125,21 +125,6 @@ void Worker::notifyFinished() unsetPendingActivity(this); } -void Worker::dispatchMessage(const String& message, PassOwnPtr<MessagePortArray> ports) -{ - RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, ports); - - if (m_onMessageListener.get()) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onMessageListener->handleEvent(evt.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/src/3rdparty/webkit/WebCore/workers/Worker.h b/src/3rdparty/webkit/WebCore/workers/Worker.h index 6bc00c1..41d39a2 100644 --- a/src/3rdparty/webkit/WebCore/workers/Worker.h +++ b/src/3rdparty/webkit/WebCore/workers/Worker.h @@ -33,6 +33,7 @@ #include "ActiveDOMObject.h" #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "MessagePort.h" #include "WorkerScriptLoaderClient.h" @@ -64,15 +65,11 @@ namespace WebCore { void terminate(); - void dispatchMessage(const String&, PassOwnPtr<MessagePortArray>); - void dispatchErrorEvent(); - virtual bool canSuspend() const; virtual void stop(); virtual bool hasPendingActivity() const; - - void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; } - EventListener* onmessage() const { return m_onMessageListener.get(); } + + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); private: Worker(const String&, ScriptExecutionContext*, ExceptionCode&); @@ -83,10 +80,7 @@ namespace WebCore { virtual void derefEventTarget() { deref(); } OwnPtr<WorkerScriptLoader> m_scriptLoader; - WorkerContextProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown. - - RefPtr<EventListener> m_onMessageListener; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/workers/Worker.idl b/src/3rdparty/webkit/WebCore/workers/Worker.idl index 3b4a3ff..9c9342b 100644 --- a/src/3rdparty/webkit/WebCore/workers/Worker.idl +++ b/src/3rdparty/webkit/WebCore/workers/Worker.idl @@ -28,7 +28,6 @@ module threads { interface [ Conditional=WORKERS, - CustomMarkFunction, GenerateNativeConverter, GenerateToJS ] Worker : AbstractWorker { diff --git a/src/3rdparty/webkit/WebCore/workers/WorkerContext.cpp b/src/3rdparty/webkit/WebCore/workers/WorkerContext.cpp index 12620f4..22e5b56 100644 --- a/src/3rdparty/webkit/WebCore/workers/WorkerContext.cpp +++ b/src/3rdparty/webkit/WebCore/workers/WorkerContext.cpp @@ -161,57 +161,6 @@ void WorkerContext::scriptImported(unsigned long, const String&) notImplemented(); } -void WorkerContext::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void WorkerContext::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool WorkerContext::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - void WorkerContext::postTask(PassRefPtr<Task> task) { thread()->runLoop().postTask(task); @@ -304,6 +253,16 @@ NotificationCenter* WorkerContext::webkitNotifications() const } #endif +EventTargetData* WorkerContext::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* WorkerContext::ensureEventTargetData() +{ + return &m_eventTargetData; +} + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/src/3rdparty/webkit/WebCore/workers/WorkerContext.h b/src/3rdparty/webkit/WebCore/workers/WorkerContext.h index a3c3820..9725cf7 100644 --- a/src/3rdparty/webkit/WebCore/workers/WorkerContext.h +++ b/src/3rdparty/webkit/WebCore/workers/WorkerContext.h @@ -31,6 +31,7 @@ #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "ScriptExecutionContext.h" #include "WorkerScriptController.h" @@ -79,8 +80,8 @@ namespace WebCore { WorkerContext* self() { return this; } WorkerLocation* location() const; void close(); - void setOnerror(PassRefPtr<EventListener> eventListener) { m_onerrorListener = eventListener; } - EventListener* onerror() const { return m_onerrorListener.get(); } + + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); // WorkerUtils virtual void importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode&); @@ -92,15 +93,6 @@ namespace WebCore { int setInterval(ScheduledAction*, int timeout); void clearInterval(int timeoutId); - // EventTarget - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } - // ScriptExecutionContext virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL); virtual void addMessage(MessageDestination, MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL); @@ -125,8 +117,11 @@ namespace WebCore { private: virtual void refScriptExecutionContext() { ref(); } virtual void derefScriptExecutionContext() { deref(); } + virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); virtual const KURL& virtualURL() const; virtual KURL virtualCompleteURL(const String&) const; @@ -140,13 +135,11 @@ namespace WebCore { OwnPtr<WorkerScriptController> m_script; WorkerThread* m_thread; - RefPtr<EventListener> m_onerrorListener; - EventListenersMap m_eventListeners; - #if ENABLE_NOTIFICATIONS mutable RefPtr<NotificationCenter> m_notifications; #endif bool m_closing; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/workers/WorkerContext.idl b/src/3rdparty/webkit/WebCore/workers/WorkerContext.idl index 6a4a7fa..17bee55 100644 --- a/src/3rdparty/webkit/WebCore/workers/WorkerContext.idl +++ b/src/3rdparty/webkit/WebCore/workers/WorkerContext.idl @@ -30,6 +30,7 @@ module threads { Conditional=WORKERS, CustomMarkFunction, DelegatingGetOwnPropertySlot, + EventTarget, ExtendsDOMGlobalObject, IsWorkerContext, LegacyParent=JSWorkerContextBase, diff --git a/src/3rdparty/webkit/WebCore/workers/WorkerMessagingProxy.cpp b/src/3rdparty/webkit/WebCore/workers/WorkerMessagingProxy.cpp index 49c88c0..3d28f9e 100644 --- a/src/3rdparty/webkit/WebCore/workers/WorkerMessagingProxy.cpp +++ b/src/3rdparty/webkit/WebCore/workers/WorkerMessagingProxy.cpp @@ -35,6 +35,8 @@ #include "DedicatedWorkerThread.h" #include "DOMWindow.h" #include "Document.h" +#include "ErrorEvent.h" +#include "ExceptionCode.h" #include "GenericWorkerTask.h" #include "MessageEvent.h" #include "ScriptExecutionContext.h" @@ -61,7 +63,7 @@ private: ASSERT(scriptContext->isWorkerContext()); DedicatedWorkerContext* context = static_cast<DedicatedWorkerContext*>(scriptContext); OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release()); - context->dispatchMessage(m_message, ports.release()); + context->dispatchEvent(MessageEvent::create(ports.release(), m_message)); context->thread()->workerObjectProxy().confirmMessageFromWorkerObject(context->hasPendingActivity()); } @@ -92,7 +94,7 @@ private: return; OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release()); - workerObject->dispatchMessage(m_message, ports.release()); + workerObject->dispatchEvent(MessageEvent::create(ports.release(), m_message)); } private: @@ -126,8 +128,7 @@ private: // We don't bother checking the askedToTerminate() flag here, because exceptions should *always* be reported even if the thread is terminated. // This is intentionally different than the behavior in MessageWorkerTask, because terminated workers no longer deliver messages (section 4.6 of the WebWorker spec), but they do report exceptions. - bool errorHandled = workerObject->dispatchScriptErrorEvent(m_errorMessage, m_sourceURL, m_lineNumber); - + bool errorHandled = !workerObject->dispatchEvent(ErrorEvent::create(m_errorMessage, m_sourceURL, m_lineNumber)); if (!errorHandled) context->reportException(m_errorMessage, m_lineNumber, m_sourceURL); } diff --git a/src/3rdparty/webkit/WebCore/workers/WorkerRunLoop.cpp b/src/3rdparty/webkit/WebCore/workers/WorkerRunLoop.cpp index 52d650f..449dd78 100644 --- a/src/3rdparty/webkit/WebCore/workers/WorkerRunLoop.cpp +++ b/src/3rdparty/webkit/WebCore/workers/WorkerRunLoop.cpp @@ -64,7 +64,7 @@ private: double m_nextFireTime; }; -class WorkerRunLoop::Task : public RefCounted<Task> { +class WorkerRunLoop::Task : public RefCounted<WorkerRunLoop::Task> { public: static PassRefPtr<Task> create(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode) { diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp index e8df36d..798ae00 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp @@ -235,56 +235,6 @@ XMLHttpRequestUpload* XMLHttpRequest::upload() return m_upload.get(); } -void XMLHttpRequest::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) - if (**listenerIter == *eventListener) - return; - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void XMLHttpRequest::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } -} - -bool XMLHttpRequest::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec) -{ - // FIXME: check for other error conditions enumerated in the spec. - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(evt->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - evt->setTarget(this); - evt->setCurrentTarget(this); - listenerIter->get()->handleEvent(evt.get(), false); - } - - return !evt->defaultPrevented(); -} - void XMLHttpRequest::changeState(State newState) { if (m_state != newState) { @@ -298,10 +248,10 @@ void XMLHttpRequest::callReadyStateChangeListener() if (!scriptExecutionContext()) return; - dispatchReadyStateChangeEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().readystatechangeEvent)); if (m_state == DONE && !m_error) - dispatchLoadEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadEvent)); } void XMLHttpRequest::setWithCredentials(bool value, ExceptionCode& ec) @@ -479,10 +429,10 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec) // Also, only async requests support upload progress events. bool forcePreflight = false; if (m_async) { - dispatchLoadStartEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent)); if (m_requestEntityBody && m_upload) { - forcePreflight = m_upload->hasListeners(); - m_upload->dispatchLoadStartEvent(); + forcePreflight = m_upload->hasEventListeners(); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent)); } } @@ -556,6 +506,10 @@ void XMLHttpRequest::abort() internalAbort(); + m_responseText = ""; + m_createdDocument = false; + m_responseXML = 0; + // Clear headers as required by the spec m_requestHeaders.clear(); @@ -567,11 +521,11 @@ void XMLHttpRequest::abort() m_state = UNSENT; } - dispatchAbortEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent)); if (!m_uploadComplete) { m_uploadComplete = true; if (m_upload && m_uploadEventsAllowed) - m_upload->dispatchAbortEvent(); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent)); } } @@ -621,11 +575,11 @@ void XMLHttpRequest::genericError() void XMLHttpRequest::networkError() { genericError(); - dispatchErrorEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().errorEvent)); if (!m_uploadComplete) { m_uploadComplete = true; if (m_upload && m_uploadEventsAllowed) - m_upload->dispatchErrorEvent(); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().errorEvent)); } internalAbort(); } @@ -633,11 +587,11 @@ void XMLHttpRequest::networkError() void XMLHttpRequest::abortError() { genericError(); - dispatchAbortEvent(); + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent)); if (!m_uploadComplete) { m_uploadComplete = true; if (m_upload && m_uploadEventsAllowed) - m_upload->dispatchAbortEvent(); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent)); } } @@ -885,12 +839,12 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon return; if (m_uploadEventsAllowed) - m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, true, static_cast<unsigned>(bytesSent), static_cast<unsigned>(totalBytesToBeSent))); if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { m_uploadComplete = true; if (m_uploadEventsAllowed) - m_upload->dispatchLoadEvent(); + m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadEvent)); } } @@ -938,7 +892,12 @@ void XMLHttpRequest::didReceiveData(const char* data, int len) m_responseText += m_decoder->decode(data, len); if (!m_error) { - updateAndDispatchOnProgress(len); + long long expectedLength = m_response.expectedContentLength(); + m_receivedLength += len; + + // FIXME: the spec requires that we dispatch the event according to the least + // frequent method between every 350ms (+/-200ms) and for every byte received. + dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, expectedLength && m_receivedLength <= expectedLength, static_cast<unsigned>(m_receivedLength), static_cast<unsigned>(expectedLength))); if (m_state != LOADING) changeState(LOADING); @@ -948,70 +907,6 @@ void XMLHttpRequest::didReceiveData(const char* data, int len) } } -void XMLHttpRequest::updateAndDispatchOnProgress(unsigned int len) -{ - long long expectedLength = m_response.expectedContentLength(); - m_receivedLength += len; - - // FIXME: the spec requires that we dispatch the event according to the least - // frequent method between every 350ms (+/-200ms) and for every byte received. - dispatchProgressEvent(expectedLength); -} - -void XMLHttpRequest::dispatchReadyStateChangeEvent() -{ - RefPtr<Event> evt = Event::create(eventNames().readystatechangeEvent, false, false); - if (m_onReadyStateChangeListener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onReadyStateChangeListener->handleEvent(evt.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - -void XMLHttpRequest::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total) -{ - RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total); - if (listener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - listener->handleEvent(evt.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - -void XMLHttpRequest::dispatchAbortEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0); -} - -void XMLHttpRequest::dispatchErrorEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0); -} - -void XMLHttpRequest::dispatchLoadEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0); -} - -void XMLHttpRequest::dispatchLoadStartEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0); -} - -void XMLHttpRequest::dispatchProgressEvent(long long expectedLength) -{ - dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, expectedLength && m_receivedLength <= expectedLength, - static_cast<unsigned>(m_receivedLength), static_cast<unsigned>(expectedLength)); -} - bool XMLHttpRequest::canSuspend() const { return !m_loader; @@ -1033,4 +928,14 @@ ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const return ActiveDOMObject::scriptExecutionContext(); } +EventTargetData* XMLHttpRequest::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* XMLHttpRequest::ensureEventTargetData() +{ + return &m_eventTargetData; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h index aa33b8b..30744a0 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h @@ -23,6 +23,7 @@ #include "ActiveDOMObject.h" #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "FormData.h" #include "ResourceResponse.h" @@ -85,32 +86,12 @@ public: XMLHttpRequestUpload* upload(); XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); } - void setOnreadystatechange(PassRefPtr<EventListener> eventListener) { m_onReadyStateChangeListener = eventListener; } - EventListener* onreadystatechange() const { return m_onReadyStateChangeListener.get(); } - - void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; } - EventListener* onabort() const { return m_onAbortListener.get(); } - - void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; } - EventListener* onerror() const { return m_onErrorListener.get(); } - - void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; } - EventListener* onload() const { return m_onLoadListener.get(); } - - void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; } - EventListener* onloadstart() const { return m_onLoadStartListener.get(); } - - void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; } - EventListener* onprogress() const { return m_onProgressListener.get(); } - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - - // useCapture is not used, even for add/remove pairing (for Firefox compatibility). - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - EventListenersMap& eventListeners() { return m_eventListeners; } + DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); using RefCounted<XMLHttpRequest>::ref; using RefCounted<XMLHttpRequest>::deref; @@ -120,6 +101,8 @@ private: virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); Document* document() const; @@ -135,8 +118,6 @@ private: virtual void didFailRedirectCheck(); virtual void didReceiveAuthenticationCancellation(const ResourceResponse&); - void updateAndDispatchOnProgress(unsigned int len); - String responseMIMEType() const; bool responseIsXML() const; @@ -159,22 +140,6 @@ private: void networkError(); void abortError(); - void dispatchReadyStateChangeEvent(); - void dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total); - void dispatchAbortEvent(); - void dispatchErrorEvent(); - void dispatchLoadEvent(); - void dispatchLoadStartEvent(); - void dispatchProgressEvent(long long expectedLength); - - RefPtr<EventListener> m_onReadyStateChangeListener; - RefPtr<EventListener> m_onAbortListener; - RefPtr<EventListener> m_onErrorListener; - RefPtr<EventListener> m_onLoadListener; - RefPtr<EventListener> m_onLoadStartListener; - RefPtr<EventListener> m_onProgressListener; - EventListenersMap m_eventListeners; - RefPtr<XMLHttpRequestUpload> m_upload; KURL m_url; @@ -217,6 +182,8 @@ private: unsigned m_lastSendLineNumber; String m_lastSendURL; ExceptionCode m_exceptionCode; + + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl index 79005e2..89d9c7f 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl @@ -30,6 +30,7 @@ module xml { interface [ CustomMarkFunction, + EventTarget, NoStaticTables ] XMLHttpRequest { // From XMLHttpRequestEventTarget diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.h b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.h index 02bfdea..27f3b8c 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.h +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.h @@ -37,7 +37,7 @@ namespace WebCore { { return adoptRef(new XMLHttpRequestProgressEvent); } - static PassRefPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total) + static PassRefPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable = false, unsigned loaded = 0, unsigned total = 0) { return adoptRef(new XMLHttpRequestProgressEvent(type, lengthComputable, loaded, total)); } diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp index 0fe329d..9d0fafc 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp @@ -41,11 +41,6 @@ XMLHttpRequestUpload::XMLHttpRequestUpload(XMLHttpRequest* xmlHttpRequest) { } -bool XMLHttpRequestUpload::hasListeners() const -{ - return m_onAbortListener || m_onErrorListener || m_onLoadListener || m_onLoadStartListener || m_onProgressListener || !m_eventListeners.isEmpty(); -} - ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const { XMLHttpRequest* xmlHttpRequest = associatedXMLHttpRequest(); @@ -54,95 +49,14 @@ ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const return xmlHttpRequest->scriptExecutionContext(); } -void XMLHttpRequestUpload::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void XMLHttpRequestUpload::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool XMLHttpRequestUpload::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec) -{ - // FIXME: check for other error conditions enumerated in the spec. - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(evt->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - evt->setTarget(this); - evt->setCurrentTarget(this); - listenerIter->get()->handleEvent(evt.get(), false); - } - - return !evt->defaultPrevented(); -} - -void XMLHttpRequestUpload::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total) -{ - RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total); - if (listener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - listener->handleEvent(evt.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(evt.release(), ec); - ASSERT(!ec); -} - -void XMLHttpRequestUpload::dispatchAbortEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0); -} - -void XMLHttpRequestUpload::dispatchErrorEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0); -} - -void XMLHttpRequestUpload::dispatchLoadEvent() -{ - dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0); -} - -void XMLHttpRequestUpload::dispatchLoadStartEvent() +EventTargetData* XMLHttpRequestUpload::eventTargetData() { - dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0); + return &m_eventTargetData; } -void XMLHttpRequestUpload::dispatchProgressEvent(long long bytesSent, long long totalBytesToBeSent) +EventTargetData* XMLHttpRequestUpload::ensureEventTargetData() { - dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, true, static_cast<unsigned>(bytesSent), static_cast<unsigned>(totalBytesToBeSent)); + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h index b4f40e0..7640643 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h @@ -28,6 +28,7 @@ #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include <wtf/HashMap.h> #include <wtf/RefCounted.h> @@ -48,8 +49,6 @@ namespace WebCore { return adoptRef(new XMLHttpRequestUpload(xmlHttpRequest)); } - bool hasListeners() const; - virtual XMLHttpRequestUpload* toXMLHttpRequestUpload() { return this; } XMLHttpRequest* associatedXMLHttpRequest() const { return m_xmlHttpRequest; } @@ -57,34 +56,11 @@ namespace WebCore { ScriptExecutionContext* scriptExecutionContext() const; - void dispatchAbortEvent(); - void dispatchErrorEvent(); - void dispatchLoadEvent(); - void dispatchLoadStartEvent(); - void dispatchProgressEvent(long long bytesSent, long long totalBytesToBeSent); - - void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; } - EventListener* onabort() const { return m_onAbortListener.get(); } - - void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; } - EventListener* onerror() const { return m_onErrorListener.get(); } - - void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; } - EventListener* onload() const { return m_onLoadListener.get(); } - - void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; } - EventListener* onloadstart() const { return m_onLoadStartListener.get(); } - - void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; } - EventListener* onprogress() const { return m_onProgressListener.get(); } - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - EventListenersMap& eventListeners() { return m_eventListeners; } + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); using RefCounted<XMLHttpRequestUpload>::ref; using RefCounted<XMLHttpRequestUpload>::deref; @@ -92,19 +68,13 @@ namespace WebCore { private: XMLHttpRequestUpload(XMLHttpRequest*); - void dispatchXMLHttpRequestProgressEvent(EventListener*, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total); - virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } - - RefPtr<EventListener> m_onAbortListener; - RefPtr<EventListener> m_onErrorListener; - RefPtr<EventListener> m_onLoadListener; - RefPtr<EventListener> m_onLoadStartListener; - RefPtr<EventListener> m_onProgressListener; - EventListenersMap m_eventListeners; + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); XMLHttpRequest* m_xmlHttpRequest; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl index 3172f68..901b47c 100644 --- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl +++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl @@ -29,8 +29,9 @@ module xml { interface [ - GenerateConstructor, CustomMarkFunction, + EventTarget, + GenerateConstructor, NoStaticTables ] XMLHttpRequestUpload { // From XMLHttpRequestEventTarget diff --git a/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp b/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp index 29e211e..f5acb38 100644 --- a/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp +++ b/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp @@ -68,7 +68,12 @@ NodeSet& Value::modifiableNodeSet() return m_data->m_nodeSet; } +#if COMPILER(WINSCW) +// FIXME --nl-- Symbian WINSCW compiler complains with 'ambiguous access to overloaded function' (double, unsigned long, unsigned int) +unsigned int Value::toBoolean() const +#else bool Value::toBoolean() const +#endif { switch (m_type) { case NodeSetValue: diff --git a/src/3rdparty/webkit/WebCore/xml/XPathValue.h b/src/3rdparty/webkit/WebCore/xml/XPathValue.h index a0cd24d..bd44c91 100644 --- a/src/3rdparty/webkit/WebCore/xml/XPathValue.h +++ b/src/3rdparty/webkit/WebCore/xml/XPathValue.h @@ -66,8 +66,11 @@ namespace WebCore { Value(Node* value) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create()) { m_data->m_nodeSet.append(value); } // This is needed to safely implement constructing from bool - with normal function overloading, any pointer type would match. +#if COMPILER(WINSCW) + Value(bool); +#else template<typename T> Value(T); - +#endif static const struct AdoptTag {} adopt; Value(NodeSet& value, const AdoptTag&) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create()) { value.swap(m_data->m_nodeSet); } @@ -80,7 +83,12 @@ namespace WebCore { const NodeSet& toNodeSet() const; NodeSet& modifiableNodeSet(); +#if COMPILER(WINSCW) + // FIXME --nl-- Symbian WINSCW compiler complains with 'ambiguous access to overloaded function' (double, unsigned long, unsigned int) + unsigned int toBoolean() const; +#else bool toBoolean() const; +#endif double toNumber() const; String toString() const; @@ -90,8 +98,9 @@ namespace WebCore { double m_number; RefPtr<ValueData> m_data; }; - +#if !COMPILER(WINSCW) template<> +#endif inline Value::Value(bool value) : m_type(BooleanValue) , m_bool(value) diff --git a/src/3rdparty/webkit/WebKit/ChangeLog b/src/3rdparty/webkit/WebKit/ChangeLog index a870e74..b317193 100644 --- a/src/3rdparty/webkit/WebKit/ChangeLog +++ b/src/3rdparty/webkit/WebKit/ChangeLog @@ -1,3 +1,26 @@ +2009-09-22 Yaar Schnitman <yaar@chromium.org> + + Reviewed by David Levin. + + Create chromium directory and ported chromium.org's features.gypi for + the webkit chromium port. + + https://bugs.webkit.org/show_bug.cgi?id=29617 + + * chromium/features.gypi: Added. + +2009-09-21 Dan Bernstein <mitz@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/4137135> iFrame with PDF not being handled correctly on + usps.com + https://bugs.webkit.org/show_bug.cgi?id=4151 + + * WebKit.xcodeproj/project.pbxproj: Added WebPDFDocumentExtras.{h,mm} + and WebJSPDFDoc.{h,mm} and changed WebPDFRepresentation to + Objective-C++. + 2009-09-07 Steve Block <steveblock@google.com> Reviewed by Adam Barth. diff --git a/src/3rdparty/webkit/WebKit/mac/Configurations/Version.xcconfig b/src/3rdparty/webkit/WebKit/mac/Configurations/Version.xcconfig index d07d57f..3229ab5 100644 --- a/src/3rdparty/webkit/WebKit/mac/Configurations/Version.xcconfig +++ b/src/3rdparty/webkit/WebKit/mac/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 532; -MINOR_VERSION = 0; +MINOR_VERSION = 1; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.cpp index 1e491c9..196f0b8 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.cpp @@ -23,13 +23,17 @@ #include "qwebframe.h" #include "qwebpage.h" #include "qwebpage_p.h" +#include "QWebPageClient.h" #include <QtGui/QGraphicsScene> #include <QtGui/QGraphicsView> #include <QtGui/qapplication.h> #include <QtGui/qgraphicssceneevent.h> #include <QtGui/qstyleoption.h> +#if defined(Q_WS_X11) +#include <QX11Info> +#endif -class QWebGraphicsItemPrivate { +class QWebGraphicsItemPrivate : public QWebPageClient { public: QWebGraphicsItemPrivate(QWebGraphicsItem* parent) : q(parent) @@ -38,10 +42,17 @@ public: , progress(1.0) {} - void _q_doScroll(int dx, int dy, const QRect&); + virtual void scroll(int dx, int dy, const QRect&); + virtual void update(const QRect& dirtyRect); + + virtual QCursor cursor() const; + virtual void updateCursor(const QCursor& cursor); + + virtual int screenNumber() const; + virtual WId winId() const; + void _q_doLoadProgress(int progress); void _q_doLoadFinished(bool success); - void _q_doUpdate(const QRect& dirtyRect); void _q_setStatusBarMessage(const QString& message); QWebGraphicsItem* q; @@ -74,16 +85,48 @@ void QWebGraphicsItemPrivate::_q_doLoadFinished(bool success) emit q->loadFailed(); } -void QWebGraphicsItemPrivate::_q_doScroll(int dx, int dy, const QRect& rectToScroll) +void QWebGraphicsItemPrivate::scroll(int dx, int dy, const QRect& rectToScroll) { q->scroll(qreal(dx), qreal(dy), QRectF(rectToScroll)); } -void QWebGraphicsItemPrivate::_q_doUpdate(const QRect & dirtyRect) +void QWebGraphicsItemPrivate::update(const QRect & dirtyRect) { q->update(QRectF(dirtyRect)); } +QCursor QWebGraphicsItemPrivate::cursor() const +{ + return q->cursor(); +} + +void QWebGraphicsItemPrivate::updateCursor(const QCursor& cursor) +{ + q->setCursor(cursor); +} + +int QWebGraphicsItemPrivate::screenNumber() const +{ +#if defined(Q_WS_X11) + const QList<QGraphicsView*> views = q->scene()->views(); + + if (!views.isEmpty()) + return views.at(0)->x11Info().screen(); +#endif + + return 0; +} + +WId QWebGraphicsItemPrivate::winId() const +{ + const QList<QGraphicsView*> views = q->scene()->views(); + + if (!views.isEmpty()) + return views.at(0)->winId(); + + return 0; +} + void QWebGraphicsItemPrivate::_q_setStatusBarMessage(const QString& s) { statusBarMessage = s; @@ -175,6 +218,24 @@ bool QWebGraphicsItem::sceneEvent(QEvent* event) bool QWebGraphicsItem::event(QEvent* event) { // Re-implemented in order to allows fixing event-related bugs in patch releases. + + if (d->page) { +#ifndef QT_NO_CURSOR +#if QT_VERSION >= 0x040400 + } else if (event->type() == QEvent::CursorChange) { + // An unsetCursor will set the cursor to Qt::ArrowCursor. + // Thus this cursor change might be a QWidget::unsetCursor() + // If this is not the case and it came from WebCore, the + // QWebPageClient already has set its cursor internally + // to Qt::ArrowCursor, so updating the cursor is always + // right, as it falls back to the last cursor set by + // WebCore. + // FIXME: Add a QEvent::CursorUnset or similar to Qt. + if (cursor().shape() == Qt::ArrowCursor) + d->resetCursor(); +#endif +#endif + } return QGraphicsWidget::event(event); } @@ -193,6 +254,7 @@ void QWebGraphicsItem::setPage(QWebPage* page) return; if (d->page) { + d->page->d->client = 0; // unset the page client if (d->page->parent() == this) delete d->page; else @@ -202,6 +264,7 @@ void QWebGraphicsItem::setPage(QWebPage* page) d->page = page; if (!d->page) return; + d->page->d->client = d; // set the page client QSize size = geometry().size().toSize(); page->setViewportSize(size); @@ -220,10 +283,6 @@ void QWebGraphicsItem::setPage(QWebPage* page) this, SLOT(_q_doLoadProgress(int))); connect(d->page, SIGNAL(loadFinished(bool)), this, SLOT(_q_doLoadFinished(bool))); - connect(d->page, SIGNAL(repaintRequested(QRect)), - this, SLOT(_q_doUpdate(const QRect&))); - connect(d->page, SIGNAL(scrollRequested(int, int, const QRect&)), - this, SLOT(_q_doScroll(int, int, const QRect&))); connect(d->page, SIGNAL(statusBarMessage(const QString&)), this, SLOT(_q_setStatusBarMessage(const QString&))); } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.h index 223ac42..2c6817a 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebgraphicsitem.h @@ -133,10 +133,8 @@ protected: virtual bool sceneEvent(QEvent*); private: - Q_PRIVATE_SLOT(d, void _q_doScroll(int dx, int dy, const QRect&)) Q_PRIVATE_SLOT(d, void _q_doLoadProgress(int progress)) Q_PRIVATE_SLOT(d, void _q_doLoadFinished(bool success)) - Q_PRIVATE_SLOT(d, void _q_doUpdate(const QRect& dirtyRect)) Q_PRIVATE_SLOT(d, void _q_setStatusBarMessage(const QString& message)) QWebGraphicsItemPrivate* const d; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory.cpp index 7923275..5752d66 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "qwebhistory.h" #include "qwebhistory_p.h" +#include "qwebframe_p.h" #include "PlatformString.h" #include "Image.h" @@ -267,6 +268,8 @@ void QWebHistory::clear() lst->setCapacity(capacity); //revert capacity lst->addItem(current.get()); //insert old current item lst->goToItem(current.get()); //and set it as current again + + d->page()->updateNavigationActions(); } /*! @@ -353,9 +356,11 @@ bool QWebHistory::canGoForward() const */ void QWebHistory::back() { - d->lst->goBack(); - WebCore::Page* page = d->lst->page(); - page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + if (canGoBack()) { + d->lst->goBack(); + WebCore::Page* page = d->lst->page(); + page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + } } /*! @@ -366,9 +371,11 @@ void QWebHistory::back() */ void QWebHistory::forward() { - d->lst->goForward(); - WebCore::Page* page = d->lst->page(); - page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + if (canGoForward()) { + d->lst->goForward(); + WebCore::Page* page = d->lst->page(); + page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + } } /*! @@ -516,6 +523,8 @@ bool QWebHistory::restoreState(const QByteArray& buffer) default: {} // result is false; } + d->page()->updateNavigationActions(); + return result; }; @@ -597,4 +606,7 @@ QDataStream& operator>>(QDataStream& stream, QWebHistory& history) return stream; } - +QWebPagePrivate* QWebHistoryPrivate::page() +{ + return QWebFramePrivate::kit(lst->page()->mainFrame())->page()->handle(); +} diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory_p.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory_p.h index 809d405..a6682cd 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory_p.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebhistory_p.h @@ -25,6 +25,8 @@ #include <QtCore/qglobal.h> #include <QtCore/qshareddata.h> +class QWebPagePrivate; + class Q_AUTOTEST_EXPORT QWebHistoryItemPrivate : public QSharedData { public: static QExplicitlySharedDataPointer<QWebHistoryItemPrivate> get(QWebHistoryItem* q) @@ -57,6 +59,9 @@ public: { lst->deref(); } + + QWebPagePrivate* page(); + WebCore::BackForwardList* lst; }; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp index 5a66cc6..4578dc9 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp @@ -28,8 +28,6 @@ #include <QResizeEvent> -// TODO: handle the "Always enable" commands with QWebSettings - /*! \class QWebInspector \since 4.6 @@ -44,6 +42,14 @@ \snippet webkitsnippets/qtwebkit_qwebinspector_snippet.cpp 0 + \note A QWebInspector will display a blank widget if either: + \list + \o page() is null + \o QWebSettings::DeveloperExtrasEnabled is false + \endlist + + \section1 Resources + Most of the resources needed by the inspector are owned by the associated QWebPage and are allocated the first time that: \list @@ -56,13 +62,16 @@ the first emission of QWebPage::webInspectorTriggered() to save additional resources. - \note A QWebInspector will display a blank widget if either: - \list - \o page() is null - \o QWebSettings::DeveloperExtrasEnabled is false - \endlist + \section1 Inspector configuration persistence + + The inspector allows the user to configure some options through its + interface (e.g. the resource tracking "Always enable" option). + These settings are persisted automatically by QtWebKit using QSettings. - \sa QWebPage::webInspectorTriggered() + However since the QSettings object is instantiated using the empty + constructor, QCoreApplication::setOrganizationName() and + QCoreApplication::setApplicationName() must be called within your + application to enable the persistence of these options. */ /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 98c0770..a6942a4 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -256,6 +256,7 @@ static inline Qt::DropAction dragOpToDropAction(unsigned actions) QWebPagePrivate::QWebPagePrivate(QWebPage *qq) : q(qq) + , client(0) , view(0) , inspectorFrontend(0) , inspector(0) @@ -1554,8 +1555,10 @@ QWebHistory *QWebPage::history() const */ void QWebPage::setView(QWidget *view) { - d->view = view; - setViewportSize(view ? view->size() : QSize(0, 0)); + if (d->view != view) { + d->view = view; + setViewportSize(view ? view->size() : QSize(0, 0)); + } } /*! @@ -2909,9 +2912,11 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const case QSysInfo::WV_VISTA: ver = "Windows NT 6.0"; break; +#if QT_VERSION > 0x040500 case QSysInfo::WV_WINDOWS7: ver = "Windows NT 6.1"; break; +#endif case QSysInfo::WV_CE: ver = "Windows CE"; break; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h index f765f98..9f4216a 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h @@ -56,6 +56,7 @@ class QBitArray; QT_END_NAMESPACE class QWebInspector; +class QWebPageClient; class QWebPagePrivate { public: @@ -129,10 +130,11 @@ public: QPointer<QWebFrame> mainFrame; QWebPage *q; + QWebPageClient* client; #ifndef QT_NO_UNDOSTACK QUndoStack *undoStack; #endif - QWidget *view; + QWidget* view; bool insideOpenCall; quint64 m_totalBytes; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp index e99ebbf..5f74f36 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp @@ -440,7 +440,10 @@ void QWebSettings::resetFontSize(FontSize type) /*! Specifies the location of a user stylesheet to load with every web page. - The \a location can be a URL or a path on the local filesystem. + The \a location must be either a path on the local filesystem, or a data URL + with UTF-8 and Base64 encoded data, such as: + + "data:text/css;charset=utf-8;base64,cCB7IGJhY2tncm91bmQtY29sb3I6IHJlZCB9Ow==;" \sa userStyleSheetUrl() */ @@ -635,7 +638,15 @@ void QWebSettings::clearMemoryCaches() } /*! - Sets the maximum number of pages to hold in the memory cache to \a pages. + Sets the maximum number of pages to hold in the memory page cache to \a pages. + + The Page Cache allows for a nicer user experience when navigating forth or back + to pages in the forward/back history, by pausing and resuming up to \a pages + per page group. + + For more information about the feature, please refer to: + + http://webkit.org/blog/427/webkit-page-cache-i-the-basics/ */ void QWebSettings::setMaximumPagesInCache(int pages) { diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index d12de94..c7515ab 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "qwebview.h" + +#include "QWebPageClient.h" #include "qwebframe.h" #include "qwebpage_p.h" @@ -29,14 +31,28 @@ #include "qprinter.h" #include "qdir.h" #include "qfile.h" +#if defined(Q_WS_X11) +#include <QX11Info> +#endif -class QWebViewPrivate { +class QWebViewPrivate : public QWebPageClient { public: QWebViewPrivate(QWebView *view) : view(view) , page(0) , renderHints(QPainter::TextAntialiasing) - {} + { + Q_ASSERT(view); + } + + virtual void scroll(int dx, int dy, const QRect&); + virtual void update(const QRect& dirtyRect); + + virtual QCursor cursor() const; + virtual void updateCursor(const QCursor& cursor); + + virtual int screenNumber() const; + virtual WId winId() const; void _q_pageDestroyed(); @@ -46,6 +62,44 @@ public: QPainter::RenderHints renderHints; }; +void QWebViewPrivate::scroll(int dx, int dy, const QRect& rectToScroll) +{ + view->scroll(qreal(dx), qreal(dy), rectToScroll); +} + +void QWebViewPrivate::update(const QRect & dirtyRect) +{ + view->update(dirtyRect); +} + +QCursor QWebViewPrivate::cursor() const +{ + return view->cursor(); +} + +void QWebViewPrivate::updateCursor(const QCursor& cursor) +{ + view->setCursor(cursor); +} + +int QWebViewPrivate::screenNumber() const +{ +#if defined(Q_WS_X11) + if (view) + return view->x11Info().screen(); +#endif + + return 0; +} + +WId QWebViewPrivate::winId() const +{ + if (view) + return view->winId(); + + return 0; +} + void QWebViewPrivate::_q_pageDestroyed() { page = 0; @@ -195,6 +249,7 @@ void QWebView::setPage(QWebPage* page) if (d->page == page) return; if (d->page) { + d->page->d->client = 0; // unset the page client if (d->page->parent() == this) delete d->page; else @@ -203,6 +258,7 @@ void QWebView::setPage(QWebPage* page) d->page = page; if (d->page) { d->page->setView(this); + d->page->d->client = d; // set the page client d->page->setPalette(palette()); // #### connect signals QWebFrame *mainFrame = d->page->mainFrame(); @@ -682,24 +738,16 @@ bool QWebView::event(QEvent *e) #ifndef QT_NO_CURSOR #if QT_VERSION >= 0x040400 } else if (e->type() == QEvent::CursorChange) { - // might be a QWidget::unsetCursor() - if (cursor().shape() == Qt::ArrowCursor) { - QVariant prop = property("WebCoreCursor"); - if (prop.isValid()) { - QCursor webCoreCursor = qvariant_cast<QCursor>(prop); - if (webCoreCursor.shape() != Qt::ArrowCursor) - setCursor(webCoreCursor); - } - } - } else if (e->type() == QEvent::DynamicPropertyChange) { - const QByteArray& propName = static_cast<QDynamicPropertyChangeEvent *>(e)->propertyName(); - if (!qstrcmp(propName, "WebCoreCursor")) { - QVariant prop = property("WebCoreCursor"); - if (prop.isValid()) { - QCursor webCoreCursor = qvariant_cast<QCursor>(prop); - setCursor(webCoreCursor); - } - } + // An unsetCursor will set the cursor to Qt::ArrowCursor. + // Thus this cursor change might be a QWidget::unsetCursor() + // If this is not the case and it came from WebCore, the + // QWebPageClient already has set its cursor internally + // to Qt::ArrowCursor, so updating the cursor is always + // right, as it falls back to the last cursor set by + // WebCore. + // FIXME: Add a QEvent::CursorUnset or similar to Qt. + if (cursor().shape() == Qt::ArrowCursor) + d->resetCursor(); #endif #endif } else if (e->type() == QEvent::Leave) diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index c4c9523..7020ec0 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,220 @@ +2009-09-24 Martin Smith <msmith@trolltech.com> + + Reviewed by Simon Hausmann. + + qdoc: Added \brief texts to all the since 4.6 functions. + + * Api/qwebhistory.cpp: + +2009-09-23 J-P Nurmi <jpnurmi@gmail.com> + + Reviewed by Simon Hausmann. + + Prevent QWebPage::setView() from changing the viewport size on the fly + in case the view doesn't actually change. QWebPage::setView() is + called upon every QWebGraphicsItem::hoverMoveEvent(), which forced + the viewport size to be equal to the size of the whole graphics view. + + https://bugs.webkit.org/show_bug.cgi?id=29676 + + * Api/qwebpage.cpp: + (QWebPage::setView): + +2009-09-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Crash fix in QWebHistory back and forward methods. + + QWebHistory::back() and QWebHistory::forward() were crashing on + ASSERT in WebCore::BackForwardList. The methods should check + canGoBack() and canGoForward() at the beginning. + + https://bugs.webkit.org/show_bug.cgi?id=29675 + + * Api/qwebhistory.cpp: + (QWebHistory::back): + (QWebHistory::forward): + +2009-09-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Bug fix. QWebHistory should call QWebPage::updateNavigationActions + + In QWebHistory's methods that change item count or current item call + to QWebPage::updateNavigationActions should be executed. + QWebHistory::clear() and QWebHistory::restorState() were changed. + New helper method, QWebPagePrivate accesor, were created in + QWebHistoryPrivate class. + Two autotest were developed. + + https://bugs.webkit.org/show_bug.cgi?id=29246 + + * Api/qwebhistory.cpp: + (QWebHistory::clear): + (QWebHistory::restoreState): + (QWebHistoryPrivate::page): + * Api/qwebhistory_p.h: + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::saveAndRestore_1): + (tst_QWebHistory::clear): + +2009-09-23 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Need to guard QX11Info include with Q_WS_X11. + That class may not be available (in QT 4.5 for Symbian, for instance). + Completes fixes in r48627 and r48604. + + * Api/qwebgraphicsitem.cpp: + * Api/qwebview.cpp: + +2009-09-22 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add default timeout while waiting for signals in QWebPage auto + tests. + https://bugs.webkit.org/show_bug.cgi?id=29637 + + * tests/qwebpage/tst_qwebpage.cpp: + (waitForSignal): + +2009-09-22 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reivewed by Simon Hausmann. + + Fix the Qt/Mac build after r48604 (Implement new QWebPageClient class) + + There's no QWidget::x11Info() on Mac, and setPlatformPluginWidget() + takes a QWidget*, not a QWebPageClient* + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItemPrivate::screenNumber): + * Api/qwebview.cpp: + (QWebViewPrivate::screenNumber): + +2009-09-21 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + For Qt, platformPageClient() will now return a class derived from + the QWebPageClient, so the patch adapts our Qt hooks to go though + this class and not depend on the QWebView. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItemPrivate::scroll): + (QWebGraphicsItemPrivate::update): + (QWebGraphicsItemPrivate::cursor): + (QWebGraphicsItemPrivate::updateCursor): + (QWebGraphicsItemPrivate::screenNumber): + (QWebGraphicsItemPrivate::winId): + (QWebGraphicsItem::event): + (QWebGraphicsItem::setPage): + * Api/qwebgraphicsitem.h: + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + * Api/qwebpage_p.h: + * Api/qwebview.cpp: + (QWebViewPrivate::scroll): + (QWebViewPrivate::update): + (QWebViewPrivate::cursor): + (QWebViewPrivate::updateCursor): + (QWebViewPrivate::screenNumber): + (QWebViewPrivate::winId): + (QWebView::setPage): + (QWebView::event): + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::repaint): + (WebCore::ChromeClientQt::scroll): + (WebCore::ChromeClientQt::platformPageClient): + +2009-09-21 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29609 + Build fix for windows when using Qt 4.5.0. + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + +2009-09-19 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29345 + The tests of QWebFrame did not use QTRY_VERIFY for + tests involving the event loop. + + * tests/qwebframe/tst_qwebframe.cpp: + * tests/util.h: Added. Copy of tests/shared/util.h of Qt + +2009-09-19 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Add an autotest stub for QWebGraphicsItem. + + It just calls all the functions and makes sure they don't crash. + + * tests/qwebgraphicsitem/qwebgraphicsitem.pro: Added. + * tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp: Added. + (tst_QWebGraphicsItem::qwebgraphicsitem): + * tests/tests.pro: + +2009-09-18 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Eric Seidel. + + Corrected the Symbian specific UID3 values to be assigned + from the "unprotected" pool that permits self-signing of + those test and demo executables. (Added new UID3 values + where they were missing for new components.) + + * QGVLauncher/QGVLauncher.pro: + * QtLauncher/QtLauncher.pro: + * tests/benchmarks/loading/tst_loading.pro: + * tests/benchmarks/painting/tst_painting.pro: + * tests/qwebelement/qwebelement.pro: + * tests/qwebframe/qwebframe.pro: + * tests/qwebhistory/qwebhistory.pro: + * tests/qwebhistoryinterface/qwebhistoryinterface.pro: + * tests/qwebpage/qwebpage.pro: + * tests/qwebplugindatabase/qwebplugindatabase.pro: + * tests/qwebview/qwebview.pro: + +2009-09-17 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Make PlatformWindow return something else than PlatformWidget + https://bugs.webkit.org/show_bug.cgi?id=29085 + + Reflect the rename of platformWindow and it's return type. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::platformPageClient): + * WebCoreSupport/ChromeClientQt.h: + +2009-09-18 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add persistence support for configuration options in the + inspector. + + * Api/qwebinspector.cpp: + * QtLauncher/main.cpp: + (main): + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::populateSetting): + (WebCore::InspectorClientQt::storeSetting): + (WebCore::variantToSetting): + (WebCore::settingToVariant): + 2009-09-18 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Ariya Hidayat. @@ -20,6 +237,34 @@ (ConsolePage::javaScriptConsoleMessage): (tst_QWebPage::consoleOutput): +2009-09-17 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Improve documentation for Page Cache. + + * Api/qwebsettings.cpp: + +2009-09-17 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Update QWebSettings::setUserStyleSheetUrl() docs and test + + https://bugs.webkit.org/show_bug.cgi?id=29081 + + The documentation now specifies that the URL has to be a local file + or a a data-URL (with utf-8 and base64-encoded data), as these are the + only two schemes that the current code path accepts. + + The auto-test has been updated to reflect this limitation. + + At a later point we should concider adding API for the new way of + doing both user defined stylesheets and scripts. + + * Api/qwebsettings.cpp: + * tests/qwebpage/tst_qwebpage.cpp: + 2009-09-17 Janne Koskinen <janne.p.koskinen@digia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/QGVLauncher/QGVLauncher.pro b/src/3rdparty/webkit/WebKit/qt/QGVLauncher/QGVLauncher.pro deleted file mode 100644 index b883b52..0000000 --- a/src/3rdparty/webkit/WebKit/qt/QGVLauncher/QGVLauncher.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE = app -SOURCES += main.cpp -CONFIG -= app_bundle -CONFIG += uitools -DESTDIR = ../../../bin - -include(../../../WebKit.pri) - -QT += network -macx:QT+=xml -QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR - -symbian:TARGET.UID3 = 0x200267D0 diff --git a/src/3rdparty/webkit/WebKit/qt/QGVLauncher/main.cpp b/src/3rdparty/webkit/WebKit/qt/QGVLauncher/main.cpp deleted file mode 100644 index 9d4742a..0000000 --- a/src/3rdparty/webkit/WebKit/qt/QGVLauncher/main.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> - * Copyright (C) 2006 Zack Rusin <zack@kde.org> - * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> - * Copyright (C) 2009 Kenneth Christiansen <kenneth@webkit.org> - * Copyright (C) 2009 Antonio Gomes <antonio.gomes@openbossa.org> - * - * 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. - */ - -#include <QDebug> -#include <QFile> -#include <QGraphicsScene> -#include <QGraphicsView> -#include <QGraphicsWidget> -#include <QNetworkRequest> -#include <QTextStream> -#include <QVector> -#include <QtGui> -#include <QtNetwork/QNetworkProxy> -#include <cstdio> -#include <qwebelement.h> -#include <qwebframe.h> -#include <qwebgraphicsitem.h> -#include <qwebpage.h> -#include <qwebsettings.h> -#include <qwebview.h> - -class WebPage : public QWebPage { - Q_OBJECT - -public: - WebPage(QWidget* parent = 0) : QWebPage(parent) - { - applyProxy(); - } - virtual QWebPage* createWindow(QWebPage::WebWindowType); - -private: - void applyProxy(); -}; - -class MainView : public QGraphicsView { - Q_OBJECT - -public: - MainView(QWidget* parent) : QGraphicsView(parent), m_mainWidget(0) - { - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - } - - void setMainWidget(QGraphicsWidget* widget) - { - QRectF rect(QRect(QPoint(0, 0), size())); - widget->setGeometry(rect); - m_mainWidget = widget; - } - - void resizeEvent(QResizeEvent* event) - { - QGraphicsView::resizeEvent(event); - if (!m_mainWidget) - return; - QRectF rect(QPoint(0, 0), event->size()); - m_mainWidget->setGeometry(rect); - } - -public slots: - void flip() - { -#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) - QSizeF center = m_mainWidget->boundingRect().size() / 2; - QPointF centerPoint = QPointF(center.width(), center.height()); - m_mainWidget->setTransformOriginPoint(centerPoint); - - m_mainWidget->setRotation(m_mainWidget->rotation() ? 0 : 180); -#endif - } - -private: - QGraphicsWidget* m_mainWidget; -}; - -class SharedScene : public QSharedData { -public: - SharedScene() - { - m_scene = new QGraphicsScene; - - m_item = new QWebGraphicsItem; - m_item->setPage(new WebPage()); - - m_scene->addItem(m_item); - m_scene->setActiveWindow(m_item); - } - - ~SharedScene() - { - delete m_item; - delete m_scene; - } - - QGraphicsScene* scene() const { return m_scene; } - QWebGraphicsItem* webItem() const { return m_item; } - -private: - QGraphicsScene* m_scene; - QWebGraphicsItem* m_item; -}; - - -class MainWindow : public QMainWindow { - Q_OBJECT - -public: - MainWindow(QExplicitlySharedDataPointer<SharedScene> other) - : QMainWindow(), view(new MainView(this)), scene(other) - { - init(); - } - - MainWindow() - : QMainWindow(), view(new MainView(this)), scene(new SharedScene()) - { - init(); - } - - void init() - { - setAttribute(Qt::WA_DeleteOnClose); - - view->setScene(scene->scene()); - view->setFrameShape(QFrame::NoFrame); - view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setCentralWidget(view); - - view->setMainWidget(scene->webItem()); - - connect(scene->webItem(), SIGNAL(loadFinished()), this, SLOT(loadFinished())); - connect(scene->webItem(), SIGNAL(titleChanged(const QString&)), this, SLOT(setWindowTitle(const QString&))); - connect(scene->webItem()->page(), SIGNAL(windowCloseRequested()), this, SLOT(close())); - - resize(640, 480); - buildUI(); - } - - void load(const QString& url) - { - QUrl deducedUrl = guessUrlFromString(url); - if (!deducedUrl.isValid()) - deducedUrl = QUrl("http://" + url + "/"); - - urlEdit->setText(deducedUrl.toEncoded()); - scene->webItem()->load(deducedUrl); - scene->webItem()->setFocus(Qt::OtherFocusReason); - } - - QUrl guessUrlFromString(const QString& string) - { - QString input(string); - QFileInfo fi(input); - if (fi.exists() && fi.isRelative()) - input = fi.absoluteFilePath(); - - return QWebView::guessUrlFromString(input); - } - - QWebPage* page() const - { - return scene->webItem()->page(); - } - -protected slots: - void changeLocation() - { - load(urlEdit->text()); - } - - void loadFinished() - { - QUrl url = scene->webItem()->url(); - urlEdit->setText(url.toString()); - - QUrl::FormattingOptions opts; - opts |= QUrl::RemoveScheme; - opts |= QUrl::RemoveUserInfo; - opts |= QUrl::StripTrailingSlash; - QString s = url.toString(opts); - s = s.mid(2); - if (s.isEmpty()) - return; - //FIXME: something missing here - } - -public slots: - void newWindow(const QString &url = QString()) - { - MainWindow* mw = new MainWindow(); - mw->load(url); - mw->show(); - } - - void clone() - { - MainWindow* mw = new MainWindow(scene); - mw->show(); - } - - void flip() - { - view->flip(); - } - -private: - void buildUI() - { - QWebPage* page = scene->webItem()->page(); - urlEdit = new QLineEdit(this); - urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy()); - connect(urlEdit, SIGNAL(returnPressed()), SLOT(changeLocation())); - - QToolBar* bar = addToolBar("Navigation"); - bar->addAction(page->action(QWebPage::Back)); - bar->addAction(page->action(QWebPage::Forward)); - bar->addAction(page->action(QWebPage::Reload)); - bar->addAction(page->action(QWebPage::Stop)); - bar->addWidget(urlEdit); - - QMenu* fileMenu = menuBar()->addMenu("&File"); - fileMenu->addAction("New Window", this, SLOT(newWindow())); - fileMenu->addAction("Clone view", this, SLOT(clone())); - fileMenu->addAction("Close", this, SLOT(close())); - - QMenu* viewMenu = menuBar()->addMenu("&View"); - viewMenu->addAction(page->action(QWebPage::Stop)); - viewMenu->addAction(page->action(QWebPage::Reload)); - - QMenu* fxMenu = menuBar()->addMenu("&Effects"); - fxMenu->addAction("Flip", this, SLOT(flip())); - } - -private: - MainView* view; - QExplicitlySharedDataPointer<SharedScene> scene; - - QLineEdit* urlEdit; -}; - -QWebPage* WebPage::createWindow(QWebPage::WebWindowType) -{ - MainWindow* mw = new MainWindow; - mw->show(); - return mw->page(); -} - -void WebPage::applyProxy() -{ - QUrl proxyUrl = QWebView::guessUrlFromString(qgetenv("http_proxy")); - - if (proxyUrl.isValid() && !proxyUrl.host().isEmpty()) { - int proxyPort = (proxyUrl.port() > 0) ? proxyUrl.port() : 8080; - networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyPort)); - } -} - -int main(int argc, char** argv) -{ - QApplication app(argc, argv); - QString url = QString("file://%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html")); - - app.setApplicationName("GQVLauncher"); - - QWebSettings::setObjectCacheCapacities((16 * 1024 * 1024) / 8, (16 * 1024 * 1024) / 8, 16 * 1024 * 1024); - QWebSettings::setMaximumPagesInCache(4); - QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true); - QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); - QWebSettings::globalSettings()->setAttribute(QWebSettings::LocalStorageEnabled, true); - - const QStringList args = app.arguments(); - if (args.count() > 1) - url = args.at(1); - - MainWindow* window = new MainWindow; - window->load(url); - - for (int i = 2; i < args.count(); i++) - window->newWindow(args.at(i)); - - window->show(); - return app.exec(); -} - -#include "main.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index 9a63e85..5c65112 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -39,6 +39,7 @@ #include "WindowFeatures.h" #include "DatabaseTracker.h" #include "SecurityOrigin.h" +#include "QWebPageClient.h" #include "qwebpage.h" #include "qwebpage_p.h" @@ -308,12 +309,11 @@ void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, boo { // No double buffer, so only update the QWidget if content changed. if (contentChanged) { - // Only do implicit paints for QWebView's - if (QWebView* view = qobject_cast<QWebView*>(m_webPage->view())) { + if (platformPageClient()) { QRect rect(windowRect); rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize())); if (!rect.isEmpty()) - view->update(rect); + platformPageClient()->update(rect); } emit m_webPage->repaintRequested(windowRect); } @@ -324,9 +324,8 @@ void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, boo void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&) { - // Only do implicit paints for QWebView's - if (QWebView* view = qobject_cast<QWebView*>(m_webPage->view())) - view->scroll(delta.width(), delta.height(), scrollViewRect); + if (platformPageClient()) + platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect); emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect); } @@ -342,9 +341,9 @@ IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const return point; } -PlatformWidget ChromeClientQt::platformWindow() const +PlatformPageClient ChromeClientQt::platformPageClient() const { - return m_webPage->view(); + return m_webPage->d->client; } void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.h b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.h index 7ea6a70..196c4fc 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.h +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.h @@ -105,7 +105,7 @@ namespace WebCore { virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; - virtual PlatformWidget platformWindow() const; + virtual PlatformPageClient platformPageClient() const; virtual void contentsSizeChanged(Frame*, const IntSize&) const; virtual void scrollbarsModeDidChange() const { } diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index ce08d42..340325e 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -37,6 +37,7 @@ #include "qwebpage_p.h" #include "qwebview.h" +#include <QtCore/QSettings> #include <QtCore/QCoreApplication> #include "InspectorController.h" @@ -46,6 +47,12 @@ namespace WebCore { +static const QLatin1String settingStoragePrefix("Qt/QtWebKit/QWebInspector/"); +static const QLatin1String settingStorageTypeSuffix(".type"); + +static InspectorController::Setting variantToSetting(const QVariant& qvariant); +static QVariant settingToVariant(const InspectorController::Setting& icSetting); + class InspectorClientWebPage : public QWebPage { Q_OBJECT friend class InspectorClientQt; @@ -66,7 +73,6 @@ public: } }; - InspectorClientQt::InspectorClientQt(QWebPage* page) : m_inspectedWebPage(page) {} @@ -169,12 +175,34 @@ void InspectorClientQt::updateWindowTitle() void InspectorClientQt::populateSetting(const String& key, InspectorController::Setting& setting) { - notImplemented(); + QSettings qsettings; + if (qsettings.status() == QSettings::AccessError) { + // QCoreApplication::setOrganizationName and QCoreApplication::setApplicationName haven't been called + qWarning("QWebInspector: QSettings couldn't read configuration setting [%s].", + qPrintable(static_cast<QString>(key))); + return; + } + + QString settingKey(settingStoragePrefix + key); + QString storedValueType = qsettings.value(settingKey + settingStorageTypeSuffix).toString(); + QVariant storedValue = qsettings.value(settingKey); + storedValue.convert(QVariant::nameToType(storedValueType.toAscii().data())); + setting = variantToSetting(storedValue); } void InspectorClientQt::storeSetting(const String& key, const InspectorController::Setting& setting) { - notImplemented(); + QSettings qsettings; + if (qsettings.status() == QSettings::AccessError) { + qWarning("QWebInspector: QSettings couldn't persist configuration setting [%s].", + qPrintable(static_cast<QString>(key))); + return; + } + + QVariant valueToStore = settingToVariant(setting); + QString settingKey(settingStoragePrefix + key); + qsettings.setValue(settingKey, valueToStore); + qsettings.setValue(settingKey + settingStorageTypeSuffix, QVariant::typeToName(valueToStore.type())); } void InspectorClientQt::removeSetting(const String& key) @@ -182,6 +210,68 @@ void InspectorClientQt::removeSetting(const String& key) notImplemented(); } +static InspectorController::Setting variantToSetting(const QVariant& qvariant) +{ + InspectorController::Setting retVal; + + switch (qvariant.type()) { + case QVariant::Bool: + retVal.set(qvariant.toBool()); + break; + case QVariant::Double: + retVal.set(qvariant.toDouble()); + break; + case QVariant::Int: + retVal.set((long)qvariant.toInt()); + break; + case QVariant::String: + retVal.set(qvariant.toString()); + break; + case QVariant::StringList: { + QStringList qsList = qvariant.toStringList(); + int listCount = qsList.count(); + Vector<String> vector(listCount); + for (int i = 0; i < listCount; ++i) + vector[i] = qsList[i]; + retVal.set(vector); + break; + } + } + + return retVal; +} + +static QVariant settingToVariant(const InspectorController::Setting& icSetting) +{ + QVariant retVal; + + switch (icSetting.type()) { + case InspectorController::Setting::StringType: + retVal.setValue(static_cast<QString>(icSetting.string())); + break; + case InspectorController::Setting::StringVectorType: { + const Vector<String>& vector = icSetting.stringVector(); + Vector<String>::const_iterator iter; + QStringList qsList; + for (iter = vector.begin(); iter != vector.end(); ++iter) + qsList << *iter; + retVal.setValue(qsList); + break; + } + case InspectorController::Setting::DoubleType: + retVal.setValue(icSetting.doubleValue()); + break; + case InspectorController::Setting::IntegerType: + retVal.setValue((int)icSetting.integerValue()); + break; + case InspectorController::Setting::BooleanType: + retVal.setValue(icSetting.booleanValue()); + break; + } + + return retVal; +} + } #include "InspectorClientQt.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/loading/tst_loading.pro b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/loading/tst_loading.pro index af0387e..80717c2 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/loading/tst_loading.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/loading/tst_loading.pro @@ -4,3 +4,5 @@ include(../../../../../WebKit.pri) SOURCES += tst_loading.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian:TARGET.UID3 = 0xA000E541 diff --git a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.pro b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.pro index 496210e..f45d804 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.pro @@ -4,3 +4,5 @@ include(../../../../../WebKit.pri) SOURCES += tst_painting.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian:TARGET.UID3 = 0xA000E542 diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebelement/qwebelement.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebelement/qwebelement.pro index ea2bc79..0a140ad 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebelement/qwebelement.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebelement/qwebelement.pro @@ -6,4 +6,4 @@ RESOURCES += qwebelement.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C3 +symbian:TARGET.UID3 = 0xA000E53A diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/qwebframe.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/qwebframe.pro index a3e099b..81037c3 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/qwebframe.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/qwebframe.pro @@ -6,4 +6,4 @@ RESOURCES += qwebframe.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C6 +symbian:TARGET.UID3 = 0xA000E53D diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index 561087f..729b971 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -34,6 +34,7 @@ #include <QNetworkRequest> #include <QNetworkReply> #include <qsslerror.h> +#include "../util.h" //TESTED_CLASS= //TESTED_FILES= @@ -2446,23 +2447,17 @@ void tst_QWebFrame::popupFocus() view.resize(400, 100); view.show(); view.setFocus(); - QTest::qWait(200); - QVERIFY2(view.hasFocus(), - "The WebView should be created"); + QTRY_VERIFY(view.hasFocus()); // open the popup by clicking. check if focus is on the popup QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(25, 25)); QObject* webpopup = firstChildByClassName(&view, "WebCore::QWebPopup"); QComboBox* combo = qobject_cast<QComboBox*>(webpopup); - QTest::qWait(500); - QVERIFY2(!view.hasFocus() && combo->view()->hasFocus(), - "Focus sould be on the Popup"); + QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup // hide the popup and check if focus is on the page combo->hidePopup(); - QTest::qWait(500); - QVERIFY2(view.hasFocus() && !combo->view()->hasFocus(), - "Focus sould be back on the WebView"); + QTRY_VERIFY(view.hasFocus() && !combo->view()->hasFocus()); // Focus should be back on the WebView // triple the flashing time, should at least blink twice already int delay = qApp->cursorFlashTime() * 3; @@ -2630,16 +2625,16 @@ void tst_QWebFrame::hasSetFocus() QCOMPARE(loadSpy.size(), 2); m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); for (int i = 0; i < children.size(); ++i) { children.at(i)->setFocus(); - QVERIFY(children.at(i)->hasFocus()); + QTRY_VERIFY(children.at(i)->hasFocus()); QVERIFY(!m_page->mainFrame()->hasFocus()); } m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); } void tst_QWebFrame::render() diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/qwebgraphicsitem.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/qwebgraphicsitem.pro new file mode 100644 index 0000000..39e90e7 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/qwebgraphicsitem.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = tst_qwebgraphicsitem +include(../../../../WebKit.pri) +SOURCES += tst_qwebgraphicsitem.cpp +QT += testlib network +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp new file mode 100644 index 0000000..731e342 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp @@ -0,0 +1,58 @@ +/* + Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <QtTest/QtTest> + +#include <qwebgraphicsitem.h> + +class tst_QWebGraphicsItem : public QObject +{ + Q_OBJECT + +private slots: + void qwebgraphicsitem(); +}; + +void tst_QWebGraphicsItem::qwebgraphicsitem() +{ + QWebGraphicsItem item; + item.url(); + item.title(); + item.icon(); + item.zoomFactor(); + item.isInteractive(); + item.progress(); + item.toHtml(); + item.history(); + item.settings(); + item.status(); + item.page(); + item.setPage(0); + item.page(); + item.setUrl(QUrl()); + item.setZoomFactor(0); + item.setInteractive(true); + item.load(QUrl()); + item.setHtml(QString()); + item.setContent(QByteArray()); +} + +QTEST_MAIN(tst_QWebGraphicsItem) + +#include "tst_qwebgraphicsitem.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/qwebhistory.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/qwebhistory.pro index 55ed414..8ee63cc 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/qwebhistory.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/qwebhistory.pro @@ -6,4 +6,4 @@ RESOURCES += tst_qwebhistory.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C4 +symbian:TARGET.UID3 = 0xA000E53B diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp index ec7a040..4f4d3c4 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp @@ -18,6 +18,7 @@ */ #include <QtTest/QtTest> +#include <QAction> #include "qwebpage.h" #include "qwebview.h" @@ -296,10 +297,13 @@ void tst_QWebHistory::serialize_3() /** Simple checks should be a bit redundant to streaming operators */ void tst_QWebHistory::saveAndRestore_1() { + QAction* actionBack = page->action(QWebPage::Back); hist->back(); waitForLoadFinished.exec(); + QVERIFY(actionBack->isEnabled()); QByteArray buffer(hist->saveState()); hist->clear(); + QVERIFY(!actionBack->isEnabled()); QVERIFY(hist->count() == 1); hist->restoreState(buffer); @@ -310,6 +314,7 @@ void tst_QWebHistory::saveAndRestore_1() QCOMPARE(hist->currentItemIndex(), histsize - 2); QCOMPARE(hist->itemAt(0).title(), QString("page1")); QCOMPARE(hist->itemAt(histsize - 1).title(), QString("page") + QString::number(histsize)); + QVERIFY(actionBack->isEnabled()); } /** Check returns value if there are bad parameters. Actually, result @@ -376,16 +381,20 @@ void tst_QWebHistory::saveAndRestore_crash_3() /** ::clear */ void tst_QWebHistory::clear() { + QAction* actionBack = page->action(QWebPage::Back); + QVERIFY(actionBack->isEnabled()); hist->saveState(); QVERIFY(hist->count() > 1); hist->clear(); - QVERIFY(hist->count() == 1); //leave current item + QVERIFY(hist->count() == 1); // Leave current item. + QVERIFY(!actionBack->isEnabled()); + QWebPage* page2 = new QWebPage(this); QWebHistory* hist2 = page2->history(); QVERIFY(hist2->count() == 0); hist2->clear(); - QVERIFY(hist2->count() == 0); //do not change anything + QVERIFY(hist2->count() == 0); // Do not change anything. delete page2; } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro index 011869d..53e1afe 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro @@ -5,4 +5,4 @@ SOURCES += tst_qwebhistoryinterface.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C5 +symbian:TARGET.UID3 = 0xA000E53C diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/qwebpage.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/qwebpage.pro index e4b11c2..82ffac6 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/qwebpage.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/qwebpage.pro @@ -6,4 +6,4 @@ RESOURCES += tst_qwebpage.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C7 +symbian:TARGET.UID3 = 0xA000E53E diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 47a1426..0fb05b8 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -59,7 +59,7 @@ * \return \p true if the requested signal was received * \p false on timeout */ -static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) +static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000) { QEventLoop loop; QObject::connect(obj, signal, &loop, SLOT(quit())); @@ -208,7 +208,7 @@ public: public slots: bool shouldInterruptJavaScript() { - return true; + return true; } }; @@ -346,13 +346,13 @@ void tst_QWebPage::userStyleSheet() m_page->setNetworkAccessManager(networkManager); networkManager->requestedUrls.clear(); - m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}")); + m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64," + + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64())); m_view->setHtml("<p>hello world</p>"); - QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool)), 1000)); + QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool)))); - QVERIFY(networkManager->requestedUrls.count() >= 2); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}")); - QCOMPARE(networkManager->requestedUrls.at(1), QUrl("http://does.not/exist.png")); + QVERIFY(networkManager->requestedUrls.count() >= 1); + QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); } void tst_QWebPage::modified() @@ -674,7 +674,7 @@ void tst_QWebPage::multiplePageGroupsAndLocalStorage() view1.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path1")); qt_webpage_setGroupName(view1.page(), "group1"); - view2.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + view2.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path2")); qt_webpage_setGroupName(view2.page(), "group2"); QCOMPARE(qt_webpage_groupName(view1.page()), QString("group1")); @@ -945,7 +945,7 @@ void tst_QWebPage::textSelection() QVERIFY(page->action(QWebPage::SelectStartOfDocument) != 0); QVERIFY(page->action(QWebPage::SelectEndOfDocument) != 0); - // right now they are disabled because contentEditable is false and + // right now they are disabled because contentEditable is false and // there isn't an existing selection to modify QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), false); QCOMPARE(page->action(QWebPage::SelectPreviousChar)->isEnabled(), false); @@ -1114,14 +1114,14 @@ void tst_QWebPage::textEditing() QCOMPARE(page->action(QWebPage::AlignJustified)->isEnabled(), true); QCOMPARE(page->action(QWebPage::AlignLeft)->isEnabled(), true); QCOMPARE(page->action(QWebPage::AlignRight)->isEnabled(), true); - + // make sure these are disabled since there isn't a selection QCOMPARE(page->action(QWebPage::Cut)->isEnabled(), false); QCOMPARE(page->action(QWebPage::RemoveFormat)->isEnabled(), false); - + // make sure everything is selected page->triggerAction(QWebPage::SelectAll); - + // this is only true if there is an editable selection QCOMPARE(page->action(QWebPage::Cut)->isEnabled(), true); QCOMPARE(page->action(QWebPage::RemoveFormat)->isEnabled(), true); diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro index 5d10993..1376ca5 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro @@ -4,3 +4,5 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebplugindatabase.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian:TARGET.UID3 = 0xA000E540 diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebview/qwebview.pro b/src/3rdparty/webkit/WebKit/qt/tests/qwebview/qwebview.pro index b7e0fb1..d9d122c 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebview/qwebview.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebview/qwebview.pro @@ -5,4 +5,4 @@ SOURCES += tst_qwebview.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR -symbian:TARGET.UID3 = 0x200267C8 +symbian:TARGET.UID3 = 0xA000E53F diff --git a/src/3rdparty/webkit/WebKit/qt/tests/tests.pro b/src/3rdparty/webkit/WebKit/qt/tests/tests.pro index b5f66ee..ec496e3 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/tests.pro +++ b/src/3rdparty/webkit/WebKit/qt/tests/tests.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = qwebframe qwebpage qwebelement qwebhistoryinterface qwebplugindatabase qwebview qwebhistory +SUBDIRS = qwebframe qwebpage qwebelement qwebgraphicsitem qwebhistoryinterface qwebplugindatabase qwebview qwebhistory greaterThan(QT_MINOR_VERSION, 4): SUBDIRS += benchmarks/painting/tst_painting.pro benchmarks/loading/tst_loading.pro diff --git a/src/3rdparty/webkit/WebKit/qt/tests/util.h b/src/3rdparty/webkit/WebKit/qt/tests/util.h new file mode 100644 index 0000000..7f7e613 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/tests/util.h @@ -0,0 +1,48 @@ +/* + 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 Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// Functions and macros that really need to be in QTestLib + +// Will try to wait for the condition while allowing event processing +#define QTRY_VERIFY(__expr) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if (!(__expr)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QVERIFY(__expr); \ + } while(0) + +// Will try to wait for the condition while allowing event processing +#define QTRY_COMPARE(__expr, __expected) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ + } while(0) + |