diff options
author | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2009-10-22 17:50:52 (GMT) |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2009-10-22 18:34:20 (GMT) |
commit | 57f1983c164bc8553c6b6aa7ac320f00e5405548 (patch) | |
tree | 6cfbec33f6e385ceb5cbfa0168f4a9f27f0c8e57 /src/3rdparty/webkit/JavaScriptCore | |
parent | 5baebfc68dd67def412bcbaa7c61b43d05e6ee42 (diff) | |
download | Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.zip Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.tar.gz Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.tar.bz2 |
Updated WebKit from /home/jturcott/dev/webkit/ to qtwebkit-4.6-snapshot-22102009 ( 0639bb8e812c8923287cd5523248ca64fa5f7a50 )
Changes in WebKit/qt since the last update:
Jocelyn: fatal error from script, sha1 in src/3rdparty/webkit/VERSION is bad
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore')
111 files changed, 3060 insertions, 1505 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/API/APICast.h b/src/3rdparty/webkit/JavaScriptCore/API/APICast.h index b6d1532..b9167a8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/APICast.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/APICast.h @@ -27,6 +27,7 @@ #define APICast_h #include "JSAPIValueWrapper.h" +#include "JSGlobalObject.h" #include "JSValue.h" #include <wtf/Platform.h> #include <wtf/UnusedParam.h> @@ -118,6 +119,7 @@ inline JSContextRef toRef(JSC::ExecState* e) inline JSGlobalContextRef toGlobalRef(JSC::ExecState* e) { + ASSERT(e == e->lexicalGlobalObject()->globalExec()); return reinterpret_cast<JSGlobalContextRef>(e); } diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h index 202b119..c4bd7ad 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackConstructor.h @@ -41,9 +41,12 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } +protected: + static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h index 3a17fa2..0cf25c4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackFunction.h @@ -41,7 +41,7 @@ public: // refactor the code so this override isn't necessary static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h index 86f2f32..d19890a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSCallbackObject.h @@ -50,9 +50,12 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } +protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags; + private: virtual UString className() const; diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp index c358a84..e6626b7 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRef.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "JSContextRef.h" +#include "JSContextRefPrivate.h" #include "APICast.h" #include "InitializeThreading.h" @@ -152,3 +153,12 @@ JSContextGroupRef JSContextGetGroup(JSContextRef ctx) ExecState* exec = toJS(ctx); return toRef(&exec->globalData()); } + +JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) +{ + ExecState* exec = toJS(ctx); + exec->globalData().heap.registerThread(); + JSLock lock(exec); + + return toGlobalRef(exec->lexicalGlobalObject()->globalExec()); +} diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h new file mode 100644 index 0000000..ff014ec --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSContextRefPrivate.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSContextRefPrivate_h +#define JSContextRefPrivate_h + +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSValueRef.h> +#include <JavaScriptCore/WebKitAvailability.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +@function +@abstract Gets the global context of a JavaScript execution context. +@param ctx The JSContext whose global context you want to get. +@result ctx's global context. +*/ +JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* JSContextRefPrivate_h */ diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 05f90b9..8d6c2df 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,17 +1,1180 @@ +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some put_by_id_transition code generation. + https://bugs.webkit.org/show_bug.cgi?id=30539 + + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::testPrototype): + (JSC::JIT::privateCompilePutByIdTransition): No need to do object type + checks or read Structures and prototypes from objects: they're all known + constants at compile time. + +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added a private API for getting a global context from a context, for + clients who want to preserve a context for a later callback. + + * API/APICast.h: + (toGlobalRef): Added an ASSERT, since this function is used more often + than before. + + * API/JSContextRef.cpp: + * API/JSContextRefPrivate.h: Added. The new API. + + * API/tests/testapi.c: + (print_callAsFunction): + (main): Test the new API. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: Build and export the new API. + +2009-10-17 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some instanceof code generation. + https://bugs.webkit.org/show_bug.cgi?id=30488 + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): No need to do object type checks - + cell type checks and ImplementsDefaultHasIntance checks implicitly + supersede object type checks. + +2009-10-18 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Darin Adler. + + Use _stricmp and _strnicmp instead of deprecated stricmp and strnicmp. + https://bugs.webkit.org/show_bug.cgi?id=30474 + + stricmp and strnicmp are deprecated beginning in Visual + C++ 2005. Use _stricmp and _strnicmp instead in StringExtras.h. + + * wtf/StringExtras.h: + (strncasecmp): + (strcasecmp): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: apparently we shouldn't export those symbols? + + * JavaScriptCore.exp: + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: export some symbols. + + * JavaScriptCore.exp: + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + structure typeinfo flags should be inherited. + https://bugs.webkit.org/show_bug.cgi?id=30468 + + Add StructureFlag constant to the various JSC classes and use + it for the TypeInfo construction. This allows us to simply + accumulate flags by basing each classes StructureInfo on its parents. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSByteArray.h: + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fast for-in enumeration: Cache JSPropertyNameIterator; cache JSStrings + in JSPropertyNameIterator; inline more code. + + 1.024x as fast on SunSpider (fasta: 1.43x as fast). + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetPropertyNames): + (JSC::BytecodeGenerator::emitNextPropertyName): + * bytecompiler/BytecodeGenerator.h: Added a few extra operands to + op_get_pnames and op_next_pname so that we can track iteration state + in the register file instead of in the JSPropertyNameIterator. (To be + cacheable, the JSPropertyNameIterator must be stateless.) + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::Interpreter::privateExecute): Updated for in-RegisterFile + iteration state tracking. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_pnames): Updated for in-RegisterFile + iteration state tracking. + + (JSC::JIT::emit_op_next_pname): Inlined code generation for op_next_pname. + + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): Added has_property and to_object stubs. Removed op_next_pname + stub, since has_property is all we need anymore. + + * parser/Nodes.cpp: + (JSC::ForInNode::emitBytecode): Updated for in-RegisterFile + iteration state tracking. + + * runtime/JSCell.h: + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): Don't do caching at this layer + anymore, since we don't create a JSPropertyNameIterator at this layer. + + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): Do do caching at this layer. + (JSC::JSPropertyNameIterator::get): Updated for in-RegisterFile + iteration state tracking. + (JSC::JSPropertyNameIterator::markChildren): Mark our JSStrings. + + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::size): + (JSC::JSPropertyNameIterator::setCachedStructure): + (JSC::JSPropertyNameIterator::cachedStructure): + (JSC::JSPropertyNameIterator::setCachedPrototypeChain): + (JSC::JSPropertyNameIterator::cachedPrototypeChain): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + (JSC::Structure::setEnumerationCache): Don't store iteration state in + a JSPropertyNameIterator. Do cache a JSPropertyNameIterator in a + Structure. + + * runtime/JSValue.h: + (JSC::asCell): + * runtime/MarkStack.h: Make those mischievous #include gods happy. + + * runtime/ObjectConstructor.cpp: + + * runtime/Operations.h: + (JSC::normalizePrototypeChain): Renamed countPrototypeChainEntriesAndCheckForProxies + to normalizePrototypeChain, since it changes dictionary prototypes to + non-dictionary objects. + + * runtime/PropertyNameArray.cpp: + (JSC::PropertyNameArray::add): + * runtime/PropertyNameArray.h: + (JSC::PropertyNameArrayData::PropertyNameArrayData): + (JSC::PropertyNameArray::data): + (JSC::PropertyNameArray::size): + (JSC::PropertyNameArray::begin): + (JSC::PropertyNameArray::end): Simplified some code here to help with + current and future refactoring. + + * runtime/Protect.h: + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::removePropertyWithoutTransition): No need to clear + the enumeration cache with adding / removing properties without + transition. It is an error to add / remove properties without transition + once an object has been observed, and we can ASSERT to catch that. + + * runtime/Structure.h: + (JSC::Structure::enumerationCache): Changed the enumeration cache to + hold a JSPropertyNameIterator. + + * runtime/StructureChain.cpp: + * runtime/StructureChain.h: + (JSC::StructureChain::head): Removed StructureChain::isCacheable because + it was wrong-headed in two ways: (1) It gave up when a prototype was a + dictionary, but instead we want un-dictionary heavily accessed + prototypes; (2) It folded a test for hasDefaultGetPropertyNames() into + a generic test for "cacheable-ness", but hasDefaultGetPropertyNames() + is only releavant to for-in caching. + +2009-10-16 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Adam Roben. + + Add a Debug_All configuration to build entire stack as debug. + Change Debug_Internal to: + - stop using _debug suffix for all WebKit/Safari binaries + - not use _debug as a DLL naming suffix + - use non-debug C runtime lib. + + * JavaScriptCore.vcproj/JavaScriptCore.make: Debug build in makefile should build Debug_All. + * JavaScriptCore.vcproj/JavaScriptCore.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Renamed single configuration from "Release" to "all". + * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/jsc/jsc.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add Debug_All configuration. + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Last part -- replace HasDefaultGetPropertyNames with OverridesGetPropertyNames + flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetPropertyNames): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-10-16 Kevin Ollivier <kevino@theolliviers.com> + + wxMSW build fix, we can't use the simple hash there because the PlatformModuleVersion + structure differs. + + * wtf/Platform.h: + +2009-10-16 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement ExecutableAllocator for Symbian + https://bugs.webkit.org/show_bug.cgi?id=29946 + + Tested with YARR JIT enabled for Symbian; + This patch does not (yet) enable YARR JIT by default. + + * JavaScriptCore.pri: + * jit/ExecutableAllocator.h: + * jit/ExecutableAllocatorSymbian.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + +2009-10-15 Oliver Hunt <oliver@apple.com> + + Reviewed by Darin Adler. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 2 -- Reverse the TypeInfo HasDefaultMark flag to OverridesMarkChildren, etc + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GetterSetter.h: + (JSC::GetterSetter::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + (JSC::MarkStack::markChildren): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesMarkChildren): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 1. Reverse the HasStandardGetOwnPropertySlot flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + (JSC::JSCell::fastGetOwnPropertySlot): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetOwnPropertySlot): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> +2009-10-14 Darin Adler <darin@apple.com> + + Additions so fix for https://bugs.webkit.org/show_bug.cgi?id=18994 + can build on Windows. + + * wtf/MathExtras.h: Added llround and llroundf for Windows. + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Set ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH for plugins while we're still building stubs. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + Refactor ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + https://bugs.webkit.org/show_bug.cgi?id=30278 + + Move the definition of ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + from the make system into common code. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + ARM compiler does not understand reinterpret_cast<void*> + https://bugs.webkit.org/show_bug.cgi?id=29034 + + Change reinterpret_cast<void*> to regular C style (void*) cast + for the ARM RVCT compiler. + + * assembler/MacroAssemblerCodeRef.h: + (JSC::FunctionPtr::FunctionPtr): + * jit/JITOpcodes.cpp: Cast to FunctionPtr first + instead of directly casting to reinterpret_cast + * jit/JITStubCall.h: Ditto + change the type of m_stub + from void* to FunctionPtr. + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::call): + * jit/JITStubs.cpp: Ditto. + (JSC::DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)): + +2009-10-11 Oliver Hunt <oliver@apple.com> + + Re-enable the JIT. + + * wtf/Platform.h: + +2009-10-10 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Support for String.trim(), String.trimLeft() and String.trimRight() methods + https://bugs.webkit.org/show_bug.cgi?id=26590 + + Implement trim, trimLeft, and trimRight + + * runtime/StringPrototype.cpp: + (JSC::isTrimWhitespace): + Our normal string whitespace function does not include U+200B which + is needed for compatibility with mozilla's implementation of trim. + U+200B does not appear to be expected according to spec, however I am + choosing to be lax, and match mozilla behavior so have added this + exception. + (JSC::trimString): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Eliminated some legacy bytecode weirdness. + + Use vPC[x] subscripting instead of ++vPC to access instruction operands. + This is simpler, and often more efficient. + + To support this, and to remove use of hard-coded offsets in bytecode and + JIT code generation and dumping, calculate jump offsets from the beginning + of an instruction, rather than the middle or end. + + Also, use OPCODE_LENGTH instead of hard-coded constants for the sizes of + opcodes. + + SunSpider reports no change in JIT mode, and a 1.01x speedup in Interpreter + mode. + + * bytecode/CodeBlock.cpp: + (JSC::printConditionalJump): + (JSC::CodeBlock::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitJump): + (JSC::BytecodeGenerator::emitJumpIfTrue): + (JSC::BytecodeGenerator::emitJumpIfFalse): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply): + (JSC::BytecodeGenerator::emitComplexJumpScopes): + (JSC::BytecodeGenerator::emitJumpScopes): + (JSC::BytecodeGenerator::emitNextPropertyName): + (JSC::BytecodeGenerator::emitCatch): + (JSC::BytecodeGenerator::emitJumpSubroutine): + (JSC::prepareJumpTableForImmediateSwitch): + (JSC::prepareJumpTableForCharacterSwitch): + (JSC::prepareJumpTableForStringSwitch): + (JSC::BytecodeGenerator::endSwitch): + * bytecompiler/Label.h: + (JSC::Label::setLocation): + (JSC::Label::bind): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolve): + (JSC::Interpreter::resolveSkip): + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::resolveBase): + (JSC::Interpreter::resolveBaseAndProperty): + (JSC::Interpreter::createExceptionScope): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + (JSC::JIT::emitBinaryDoubleOp): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_loop): + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emitSlow_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emitSlow_op_loop_if_lesseq): + (JSC::JIT::emit_op_loop_if_true): + (JSC::JIT::emitSlow_op_loop_if_true): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emitSlow_op_jfalse): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emitSlow_op_jtrue): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_jsr): + (JSC::JIT::emit_op_next_pname): + (JSC::JIT::emit_op_jmp_scopes): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Migrated some code that didn't belong out of Structure. + + SunSpider says maybe 1.03x faster. + + * runtime/JSCell.h: Nixed Structure::markAggregate, and made marking of + a Structure's prototype the direct responsility of the object using it. + (Giving Structure a mark function was misleading because it implied that + all live structures get marked during GC, when they don't.) + + * runtime/JSGlobalObject.cpp: + (JSC::markIfNeeded): + (JSC::JSGlobalObject::markChildren): Added code to mark prototypes stored + on the global object. Maybe this wasn't necessary, but now we don't have + to wonder. + + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::getEnumerableNamesFromClassInfoTable): + * runtime/JSObject.h: + (JSC::JSObject::markChildrenDirect): + * runtime/PropertyNameArray.h: + * runtime/Structure.cpp: + * runtime/Structure.h: + (JSC::Structure::setEnumerationCache): + (JSC::Structure::enumerationCache): Moved property name gathering code + from Structure to JSObject because having a Structure iterate its JSObject + was a layering violation. A JSObject is implemented using a Structure; not + the other way around. + +2009-10-09 Mark Rowe <mrowe@apple.com> + + Attempt to fix the GTK release build. + + * GNUmakefile.am: Include Grammar.cpp in release builds now that + AllInOneFile.cpp is gone. + +2009-10-09 Gabor Loki <loki@inf.u-szeged.hu> + + Rubber-stamped by Eric Seidel. + + Add ARM JIT support for Gtk port (disabled by default) + https://bugs.webkit.org/show_bug.cgi?id=30228 + + * GNUmakefile.am: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: added a few more variable initializations. + + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncSearch): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Qt build fix: added missing #include. + + * jsc.cpp: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: initialize variable whose initialization the compiler + can't otherwise figure out. + + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: updated exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: fixed file name case. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + At long last, I pronounce the death of AllInOneFile.cpp. + + SunSpider reports a 1.01x speedup. + + * AllInOneFile.cpp: Removed. + * GNUmakefile.am: + * JavaScriptCore.exp: + * JavaScriptCore.gypi: + * JavaScriptCore.xcodeproj/project.pbxproj: Added missing project files + to compilation stages. + + * parser/Grammar.y: + * parser/Lexer.cpp: + * parser/Lexer.h: + (JSC::jscyylex): + * runtime/ArrayConstructor.cpp: + (JSC::constructArrayWithSizeQuirk): + * runtime/Collector.h: + * runtime/JSCell.cpp: + (JSC::JSCell::operator new): + * runtime/JSCell.h: + (JSC::JSCell::operator new): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::operator new): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::operator new): + * runtime/JSString.cpp: + * runtime/JSString.h: + (JSC::jsString): + (JSC::jsSubstring): + (JSC::jsOwnedString): + * runtime/RegExpConstructor.cpp: + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructorPrivate::RegExpConstructorPrivate): + (JSC::RegExpConstructorPrivate::lastOvector): + (JSC::RegExpConstructorPrivate::tempOvector): + (JSC::RegExpConstructorPrivate::changeLastOvector): + (JSC::RegExpConstructor::performMatch): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncMatch): + * yarr/RegexJIT.cpp: + * yarr/RegexJIT.h: + (JSC::Yarr::executeRegex): Inlined a few things that Shark said + were hot, on the presumption that AllInOneFile.cpp used to inline them + automatically. + +2009-10-08 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + Fix for JIT'ed op_call instructions (evals, constructs, etc.) + when !ENABLE(JIT_OPTIMIZE_CALL) && USE(JSVALUE32_64) + + https://bugs.webkit.org/show_bug.cgi?id=30201 + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + +2009-10-07 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: removed no longer exported symbol. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-07 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fixed <rdar://problem/5751979> Database code takes JSLock on secondary + thread, permanently slowing down JavaScript + + Removed the optional lock from Heap::protect, Heap::unprotect, and friends, + since WebCore no longer uses it. + + * JavaScriptCore.exp: + * runtime/Collector.cpp: + (JSC::Heap::protect): + (JSC::Heap::unprotect): + (JSC::Heap::markProtectedObjects): + (JSC::Heap::protectedGlobalObjectCount): + (JSC::Heap::protectedObjectCount): + (JSC::Heap::protectedObjectTypeCounts): + * runtime/Collector.h: + +2009-10-07 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for JavaScriptCore's IdentifierArena + https://bugs.webkit.org/show_bug.cgi?id=30158 + + Inherits IdentifierArena class from FastAllocBase because it has been + instantiated by 'new' in JavaScriptCore/parser/ParserArena.cpp:36. + + * parser/ParserArena.h: + +2009-10-07 Adam Roben <aroben@apple.com> + + Export DateInstance::info in a way that works on Windows + + Fixes <http://webkit.org/b/30171> + fast/dom/Window/window-postmessage-clone.html fails on Windows + + Reviewed by Anders Carlsson. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + Removed the export of DateInstance::info from here. + + * runtime/DateInstance.h: Use JS_EXPORTDATA to export + DateInstance::info, which is the required way of exporting data on + Windows. + +2009-10-07 Jørgen Lind <jorgen.lind@nokia.com> + + Reviewed by Simon Hausmann. + + When enabling or disabling the JIT through .qmake.cache, make sure + to also toggle ENABLE_YARR_JIT. + + * JavaScriptCore.pri: + +2009-10-06 Priit Laes <plaes@plaes.org> + + Reviewed by Gavin Barraclough. + + Linking fails with "relocation R_X86_64_PC32 against symbol + `cti_vm_throw'" + https://bugs.webkit.org/show_bug.cgi?id=28422 + + * jit/JITStubs.cpp: + Mark cti_vm_throw symbol as PLT-indirect symbol, so it doesn't end up + in text segment causing relocation errors on amd64 architecture. + Introduced new define SYMBOL_STRING_RELOCATION for such symbols. + +2009-10-06 Oliver Hunt <oliver@apple.com> + + Windows linking fix + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-06 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY (build fix). + + Windows build fix. + + * runtime/DateInstance.cpp: + +2009-10-05 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + It should be possible to post (clone) built-in JS objects to Workers + https://bugs.webkit.org/show_bug.cgi?id=22878 + + Expose helpers to throw correct exceptions during object graph walk + used for cloning and add a helper function to create Date instances + without going through the JS Date constructor function. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + * runtime/DateInstance.h: + * runtime/ExceptionHelpers.cpp: + (JSC::createTypeError): + * runtime/ExceptionHelpers.h: + +2009-10-06 David Levin <levin@chromium.org> + + Reviewed by Oliver Hunt. + + StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer. + https://bugs.webkit.org/show_bug.cgi?id=30095 + + * wtf/CrossThreadRefCounted.h: + Removed an unused function and assert improvement. + (WTF::CrossThreadRefCounted::isOwnedByCurrentThread): Moved out common code from asserts. + (WTF::CrossThreadRefCounted::ref): Changed assert to use the common method. + (WTF::CrossThreadRefCounted::deref): Changed assert to use the common method. + (WTF::CrossThreadRefCounted::crossThreadCopy): Since this includes a potentially + non-threadsafe operation, add an assert that the class is owned by the current thread. + +2009-10-05 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Add Symbian files to the list of excludes. + + * wscript: + +2009-10-05 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Remove precompiled header from JavaScriptCore compilation to + prevent qmake warning during autonomous compilation. + https://bugs.webkit.org/show_bug.cgi?id=30069 + + * JavaScriptCore.pro: + +2009-10-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Removed the concept of a "fast access cutoff" in arrays, because it + punished some patterns of array access too much, and made things too + complex for inlining in some cases. + + 1.3% speedup on SunSpider. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITStubs.cpp: + * jit/JITStubs.h: + (JSC::): Check m_vectorLength instead of m_fastAccessCutoff when + getting / putting from / to an array. Inline putting past the end of + the array. + + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::putSlowCase): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::canGetIndex): + (JSC::JSArray::canSetIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::markChildrenDirect): Removed m_fastAccessCutoff, and + replaced with checks for JSValue() to detect reads and writes from / to + uninitialized parts of the array. + +2009-10-02 Jonni Rainisto <jonni.rainisto@nokia.com> + + Reviewed by Darin Adler. + + Math.random() gives too low values on Win32 when _CRT_RAND_S is not defined + https://bugs.webkit.org/show_bug.cgi?id=29956 + + * wtf/RandomNumber.cpp: + (WTF::randomNumber): Added PLATFORM(WIN_OS) to handle 15bit rand() + +2009-10-02 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Take one branch instead of two to test for JSValue(). + + 1.1% SunSpider speedup. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emit_op_create_arguments): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + + * runtime/JSValue.cpp: + (JSC::JSValue::description): Added support for dumping the new empty value, + and deleted values, in debug builds. + + * runtime/JSValue.h: + (JSC::JSValue::JSValue()): Construct JSValue() with the empty value tag. + + (JSC::JSValue::JSValue(JSCell*)): Convert null pointer to the empty value + tag, to avoid having two different c++ versions of null / empty. + + (JSC::JSValue::operator bool): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + +2009-10-02 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Mark Rowe. + + <https://bugs.webkit.org/show_bug.cgi?id=29989> + Safari version number shouldn't be exposed in WebKit code + + For a WebKit version of 532.3.4: + Product version is: 5.32.3.4 (was 4.0.3.0) + File version is: 5.32.3.4 (was 4.532.3.4) + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: + +2009-10-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Rubber-stamped by Simon Hausmann. + + Fix the Qt on Mac OS X build. + + * wtf/FastMalloc.cpp: + +2009-10-02 Jørgen Lind <jorgen.lind@nokia.com> + + Reviewed by Simon Hausmann. + + Allow enabling and disabling of the JIT through a qmake variable. + + Qt's configure may set this variable through .qmake.cache if a + commandline option is given and/or the compile test for hwcap.h + failed/succeeded. + + * JavaScriptCore.pri: + +2009-10-01 Mark Rowe <mrowe@apple.com> + + Fix the Tiger build. Don't unconditionally enable 3D canvas as it is not supported on Tiger. + + * Configurations/FeatureDefines.xcconfig: + +2009-10-01 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=29187 + + Don't inline ~ListRefPtr() to work around winscw compiler forward declaration + bug regarding templated classes. + + The compiler bug is reported at: + https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812 + + The change will be reverted when the above bug is fixed in winscw compiler. + + * wtf/ListRefPtr.h: + (WTF::::~ListRefPtr): + +2009-10-01 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Allow custom memory allocation control for the whole JavaScriptCore + https://bugs.webkit.org/show_bug.cgi?id=27029 + + Since in JavaScriptCore almost every class which has been instantiated by operator new is + inherited from FastAllocBase (bug #20422), we disable customizing global operator new for the Qt-port + when USE_SYSTEM_MALLOC=0. + + Add #include <unistd.h> to FastMalloc.cpp because it's used by TCMalloc_PageHeap::scavengerThread(). + (It's needed for the functionality of TCmalloc.) + + Add TCSystemAlloc.cpp to JavaScriptCore.pri if USE_SYSTEM_MALLOC is disabled. + + * JavaScriptCore.pri: + * wtf/FastMalloc.cpp: + (WTF::sleep): + * wtf/FastMalloc.h: + +2009-09-30 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by George Staikos. + + Defines two pseudo-platforms for ARM and Thumb-2 instruction set. + https://bugs.webkit.org/show_bug.cgi?id=29122 + + Introduces WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 + macros on ARM platforms. The PLATFORM(ARM_THUMB2) should be used + when Thumb-2 instruction set is the required target. The + PLATFORM(ARM_TRADITIONAL) is for generic ARM instruction set. In + case where the code is common the PLATFORM(ARM) have to be used. + + Modified by George Wright <gwright@rim.com> to correctly work + with the RVCT-defined __TARGET_ARCH_ARM and __TARGET_ARCH_THUMB + compiler macros, as well as adding readability changes. + + * wtf/Platform.h: + +2009-09-30 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Devirtualise array toString conversion + + Tweak the implementation of Array.prototype.toString to have a fast path + when acting on a true JSArray. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + 2009-09-30 Csaba Osztrogonac <oszi@inf.u-szeged.hu> - Reviewed by NOBODY (OOPS!). + Reviewed by Geoffrey Garen. Buildfix for platforms using JSVALUE32. https://bugs.webkit.org/show_bug.cgi?id=29915 After http://trac.webkit.org/changeset/48905 the build broke in JSVALUE32 case. + Also removed unreachable code. * jit/JITArithmetic.cpp: (JSC::JIT::emit_op_add): - Declaration of "OperandTypes types" moved before first use. - Typos fixed: dst modified to result, regT2 added. - - Unnecessary code removed. + - Unreachable code removed. (JSC::JIT::emitSlow_op_add): - Missing declaration of "OperandTypes types" added. diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi index 15a0c0f..4b316c8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi @@ -1,7 +1,6 @@ { 'variables': { 'javascriptcore_files': [ - 'AllInOneFile.cpp', 'API/APICast.h', 'API/JavaScript.h', 'API/JavaScriptCore.h', @@ -19,6 +18,7 @@ 'API/JSClassRef.h', 'API/JSContextRef.cpp', 'API/JSContextRef.h', + 'API/JSContextRefPrivate.h', 'API/JSObjectRef.cpp', 'API/JSObjectRef.h', 'API/JSProfilerPrivate.cpp', diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri index 2b08980..89c483e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri @@ -137,7 +137,8 @@ SOURCES += \ interpreter/RegisterFile.cpp symbian { - SOURCES += runtime/MarkStackSymbian.cpp + SOURCES += jit/ExecutableAllocatorSymbian.cpp \ + runtime/MarkStackSymbian.cpp } else { win32-*|wince* { SOURCES += jit/ExecutableAllocatorWin.cpp \ @@ -148,6 +149,10 @@ symbian { } } +!contains(DEFINES, USE_SYSTEM_MALLOC) { + SOURCES += wtf/TCSystemAlloc.cpp +} + # AllInOneFile.cpp helps gcc analize and optimize code # Other compilers may be able to do this at link time SOURCES += \ diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro index 0cd2e1a..a1affd4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro @@ -16,7 +16,6 @@ CONFIG(QTDIR_build) { include($$QT_SOURCE_TREE/src/qbase.pri) INSTALLS = DESTDIR = $$OLDDESTDIR - PRECOMPILED_HEADER = $$PWD/../WebKit/qt/WebKit_pch.h DEFINES *= NDEBUG } diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 568260a..3681af8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/src/3rdparty/webkit/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -69,7 +69,13 @@ public: template<typename FunctionType> explicit FunctionPtr(FunctionType* value) +#if COMPILER(RVCT) + // RVTC compiler needs C-style cast as it fails with the following error + // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers + : m_value((void*)(value)) +#else : m_value(reinterpret_cast<void*>(value)) +#endif { ASSERT_VALID_CODE_POINTER(m_value); } diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp index 6bac9b9..18ca2ae 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp @@ -135,11 +135,6 @@ NEVER_INLINE static const char* debugHookName(int debugHookID) return ""; } -static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset) -{ - return it - begin + offset; -} - static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op) { int r0 = (++it)->u.operand; @@ -156,11 +151,11 @@ static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); } -static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op) +static void printConditionalJump(const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) { int r0 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, location + offset); } static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op) @@ -852,12 +847,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_loop: { int offset = (++it)->u.operand; - printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { @@ -884,56 +879,56 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_less: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_lesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_switch_imm: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_char: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_string: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_new_func: { @@ -1020,16 +1015,18 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& break; } case op_get_pnames: { - int r0 = (++it)->u.operand; - int r1 = (++it)->u.operand; + int r0 = it[0].u.operand; + int r1 = it[1].u.operand; printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + it += OPCODE_LENGTH(op_get_pnames) - 1; break; } case op_next_pname: { - int dest = (++it)->u.operand; - int iter = (++it)->u.operand; - int offset = (++it)->u.operand; - printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset)); + int dest = it[0].u.operand; + int iter = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_next_pname) - 1; break; } case op_push_scope: { @@ -1051,7 +1048,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jmp_scopes: { int scopeDelta = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); break; } case op_catch: { @@ -1074,7 +1071,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jsr: { int retAddrDst = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, location + offset); break; } case op_sret: { diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h index c9196ce..8968252 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h @@ -152,8 +152,8 @@ namespace JSC { macro(op_strcat, 4) \ macro(op_to_primitive, 3) \ \ - macro(op_get_pnames, 3) \ - macro(op_next_pname, 4) \ + macro(op_get_pnames, 6) \ + macro(op_next_pname, 7) \ \ macro(op_push_scope, 2) \ macro(op_pop_scope, 1) \ diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 8951ce3..41b5c39 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -608,8 +608,9 @@ void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp() PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target) { + size_t begin = instructions().size(); emitOpcode(target->isForward() ? op_jmp : op_loop); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -624,10 +625,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_less); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) { @@ -639,10 +642,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_lesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { @@ -653,9 +658,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null && target->isForward()) { @@ -666,16 +673,20 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); + emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -692,10 +703,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnless); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq) { @@ -707,10 +720,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnlesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_not) { @@ -721,9 +736,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jtrue); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null) { @@ -734,9 +751,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null) { @@ -747,34 +766,41 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); emitOpcode(op_jfalse); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->callFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->applyFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -1718,6 +1744,8 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro } if (nNormalScopes) { + size_t begin = instructions().size(); + // We need to remove a number of dynamic scopes to get to the next // finally block emitOpcode(op_jmp_scopes); @@ -1726,14 +1754,14 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro // If topScope == bottomScope then there isn't actually a finally block // left to emit, so make the jmp_scopes jump directly to the target label if (topScope == bottomScope) { - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } // Otherwise we just use jmp_scopes to pop a group of scopes and go // to the next instruction RefPtr<Label> nextInsn = newLabel(); - instructions().append(nextInsn->offsetFrom(instructions().size())); + instructions().append(nextInsn->bind(begin, instructions().size())); emitLabel(nextInsn.get()); } @@ -1758,27 +1786,47 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetSco if (m_finallyDepth) return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta); + size_t begin = instructions().size(); + emitOpcode(op_jmp_scopes); instructions().append(scopeDelta); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } -RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target) +RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget) +{ + size_t begin = instructions().size(); + + emitOpcode(op_get_pnames); + instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); + instructions().append(breakTarget->bind(begin, instructions().size())); + return dst; +} + +RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_next_pname); instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); instructions().append(iter->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return dst; } RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end) { #if ENABLE(JIT) - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; #else - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; #endif m_codeBlock->addExceptionHandler(info); @@ -1798,9 +1846,11 @@ RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSV PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally) { + size_t begin = instructions().size(); + emitOpcode(op_jsr); instructions().append(retAddrDst->index()); - instructions().append(finally->offsetFrom(instructions().size())); + instructions().append(finally->bind(begin, instructions().size())); emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. return finally; } @@ -1870,7 +1920,7 @@ static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1896,7 +1946,7 @@ static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1910,7 +1960,7 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t ASSERT(nodes[i]->isString()); UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep(); OffsetLocation location; - location.branchOffset = labels[i]->offsetFrom(switchAddress); + location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3); jumpTable.offsetTable.add(clause, location); } } @@ -1921,23 +1971,23 @@ void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, E m_switchContextStack.removeLast(); if (switchInfo.switchType == SwitchInfo::SwitchImmediate) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable(); - prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable(); - prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else { ASSERT(switchInfo.switchType == SwitchInfo::SwitchString); instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable(); - prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes); + prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 1a83ce9..61de173 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -312,8 +312,8 @@ namespace JSC { PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*); void emitSubroutineReturn(RegisterID* retAddrSrc); - RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); } - RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target); + RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget); + RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target); RegisterID* emitCatch(RegisterID*, Label* start, Label* end); void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); } diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h index 0b3d038..8cab1db 100644 --- a/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h +++ b/src/3rdparty/webkit/JavaScriptCore/bytecompiler/Label.h @@ -51,19 +51,17 @@ namespace JSC { m_location = location; unsigned size = m_unresolvedJumps.size(); - for (unsigned i = 0; i < size; ++i) { - unsigned j = m_unresolvedJumps[i]; - m_codeBlock->instructions()[j].u.operand = m_location - j; - } + for (unsigned i = 0; i < size; ++i) + m_codeBlock->instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first; } - int offsetFrom(int location) const + int bind(int opcode, int offset) const { if (m_location == invalidLocation) { - m_unresolvedJumps.append(location); + m_unresolvedJumps.append(std::make_pair(opcode, offset)); return 0; } - return m_location - location; + return m_location - opcode; } void ref() { ++m_refCount; } @@ -77,7 +75,7 @@ namespace JSC { bool isForward() const { return m_location == invalidLocation; } private: - typedef Vector<int, 8> JumpVector; + typedef Vector<std::pair<int, int>, 8> JumpVector; static const unsigned invalidLocation = UINT_MAX; diff --git a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h index dd34265..63cf635 100644 --- a/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/debugger/DebuggerActivation.h @@ -51,9 +51,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | JSObject::StructureFlags; + private: JSActivation* m_activation; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp index 71451d6..5b1be71 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp @@ -236,6 +236,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Lexer.h" #include "NodeConstructors.h" #include "NodeInfo.h" #include <stdlib.h> @@ -257,7 +258,6 @@ #define YYERROR_VERBOSE #endif -int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h b/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h index f912298..c8ff849 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h +++ b/src/3rdparty/webkit/JavaScriptCore/generated/StringPrototype.lut.h @@ -4,7 +4,7 @@ namespace JSC { -static const struct HashTableValue stringTableValues[33] = { +static const struct HashTableValue stringTableValues[36] = { { "toString", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 }, { "valueOf", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 }, { "charAt", DontEnum|Function, (intptr_t)stringProtoFuncCharAt, (intptr_t)1 }, @@ -37,9 +37,12 @@ static const struct HashTableValue stringTableValues[33] = { { "fontsize", DontEnum|Function, (intptr_t)stringProtoFuncFontsize, (intptr_t)1 }, { "anchor", DontEnum|Function, (intptr_t)stringProtoFuncAnchor, (intptr_t)1 }, { "link", DontEnum|Function, (intptr_t)stringProtoFuncLink, (intptr_t)1 }, + { "trim", DontEnum|Function, (intptr_t)stringProtoFuncTrim, (intptr_t)0 }, + { "trimLeft", DontEnum|Function, (intptr_t)stringProtoFuncTrimLeft, (intptr_t)0 }, + { "trimRight", DontEnum|Function, (intptr_t)stringProtoFuncTrimRight, (intptr_t)0 }, { 0, 0, 0, 0 } }; extern JSC_CONST_HASHTABLE HashTable stringTable = - { 71, 63, stringTableValues, 0 }; + { 133, 127, stringTableValues, 0 }; } // namespace diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp index 847b1fa..53964ad 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp @@ -91,8 +91,8 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc) #if USE(INTERPRETER) NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -121,9 +121,9 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP { CodeBlock* codeBlock = callFrame->codeBlock(); - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; - int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain(); + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; + int skip = vPC[3].u.operand + codeBlock->needsFullScopeChain(); ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -152,12 +152,12 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int dst = (vPC + 1)->u.operand; - JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell); + int dst = vPC[1].u.operand; + JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); ASSERT(globalObject->isGlobalObject()); - int property = (vPC + 3)->u.operand; - Structure* structure = (vPC + 4)->u.structure; - int offset = (vPC + 5)->u.operand; + int property = vPC[3].u.operand; + Structure* structure = vPC[4].u.structure; + int offset = vPC[5].u.operand; if (structure == globalObject->structure()) { callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset)); @@ -192,16 +192,16 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC) { - int dst = (vPC + 1)->u.operand; - int property = (vPC + 2)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain())); } NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { - int baseDst = (vPC + 1)->u.operand; - int propDst = (vPC + 2)->u.operand; - int property = (vPC + 3)->u.operand; + int baseDst = vPC[1].u.operand; + int propDst = vPC[2].u.operand; + int property = vPC[3].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -233,51 +233,6 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst return false; } -NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) -{ - int baseDst = (vPC + 1)->u.operand; - int funcDst = (vPC + 2)->u.operand; - int property = (vPC + 3)->u.operand; - - ScopeChainNode* scopeChain = callFrame->scopeChain(); - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - - // FIXME: add scopeDepthIsZero optimization - - ASSERT(iter != end); - - CodeBlock* codeBlock = callFrame->codeBlock(); - Identifier& ident = codeBlock->identifier(property); - JSObject* base; - do { - base = *iter; - PropertySlot slot(base); - if (base->getPropertySlot(callFrame, ident, slot)) { - // ECMA 11.2.3 says that if we hit an activation the this value should be null. - // However, section 10.2.3 says that in the case where the value provided - // by the caller is null, the global object should be used. It also says - // that the section does not apply to internal functions, but for simplicity - // of implementation we use the global object anyway here. This guarantees - // that in host objects you always get a valid object for this. - // We also handle wrapper substitution for the global object at the same time. - JSObject* thisObj = base->toThisObject(callFrame); - JSValue result = slot.getValue(callFrame, ident); - exceptionValue = callFrame->globalData().exception; - if (exceptionValue) - return false; - - callFrame->r(baseDst) = JSValue(thisObj); - callFrame->r(funcDst) = JSValue(result); - return true; - } - ++iter; - } while (iter != end); - - exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock); - return false; -} - #endif // USE(INTERPRETER) ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc) @@ -928,10 +883,10 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook #if USE(INTERPRETER) NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC) { - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); - Identifier& property = codeBlock->identifier((++vPC)->u.operand); - JSValue value = callFrame->r((++vPC)->u.operand).jsValue(); + Identifier& property = codeBlock->identifier(vPC[2].u.operand); + JSValue value = callFrame->r(vPC[3].u.operand).jsValue(); JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete); callFrame->r(dst) = JSValue(scope); @@ -983,22 +938,20 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* return; } - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - vPC[0] = getOpcode(op_put_by_id_generic); - return; - } - // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { if (structure->isDictionary()) { vPC[0] = getOpcode(op_put_by_id_generic); return; } + + // put_by_id_transition checks the prototype chain for setters. + normalizePrototypeChain(callFrame, baseCell); + vPC[0] = getOpcode(op_put_by_id_transition); vPC[4] = structure->previousID(); vPC[5] = structure; - vPC[6] = protoChain; + vPC[6] = structure->prototypeChain(callFrame); vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); return; @@ -1094,21 +1047,15 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* return; } - size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); if (!count) { vPC[0] = getOpcode(op_get_by_id_generic); return; } - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - vPC[0] = getOpcode(op_get_by_id_generic); - return; - } - vPC[0] = getOpcode(op_get_by_id_chain); vPC[4] = structure; - vPC[5] = protoChain; + vPC[5] = structure->prototypeChain(callFrame); vPC[6] = count; vPC[7] = slot.cachedOffset(); codeBlock->refStructures(vPC); @@ -1213,10 +1160,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Constructs a new empty Object instance using the original constructor, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; callFrame->r(dst) = JSValue(constructEmptyObject(callFrame)); - ++vPC; + vPC += OPCODE_LENGTH(op_new_object); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_array) { @@ -1227,13 +1174,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi The array will contain argCount elements with values taken from registers starting at register firstArg. */ - int dst = (++vPC)->u.operand; - int firstArg = (++vPC)->u.operand; - int argCount = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int firstArg = vPC[2].u.operand; + int argCount = vPC[3].u.operand; ArgList args(callFrame->registers() + firstArg, argCount); callFrame->r(dst) = JSValue(constructArray(callFrame, args)); - ++vPC; + vPC += OPCODE_LENGTH(op_new_array); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_regexp) { @@ -1243,11 +1190,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor from regexp regExp, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int regExp = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int regExp = vPC[2].u.operand; callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp))); - ++vPC; + vPC += OPCODE_LENGTH(op_new_regexp); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mov) { @@ -1255,11 +1202,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Copies register src to register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(src); - ++vPC; + vPC += OPCODE_LENGTH(op_mov); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_eq) { @@ -1269,9 +1216,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi as with the ECMAScript '==' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32()); else { @@ -1280,7 +1227,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_eq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_eq_null) { @@ -1289,17 +1236,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Checks whether register src is null, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isUndefinedOrNull()) { callFrame->r(dst) = jsBoolean(true); - ++vPC; + vPC += OPCODE_LENGTH(op_eq_null); NEXT_INSTRUCTION(); } callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_eq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_neq) { @@ -1309,9 +1256,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi equal, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32()); else { @@ -1320,7 +1267,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_neq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_neq_null) { @@ -1329,17 +1276,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Checks whether register src is not null, as with the ECMAScript '!=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isUndefinedOrNull()) { callFrame->r(dst) = jsBoolean(false); - ++vPC; + vPC += OPCODE_LENGTH(op_neq_null); NEXT_INSTRUCTION(); } callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_neq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_stricteq) { @@ -1349,12 +1296,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi equal, as with the ECMAScript '===' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2)); - ++vPC; + vPC += OPCODE_LENGTH(op_stricteq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_nstricteq) { @@ -1364,12 +1311,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi strictly equal, as with the ECMAScript '!==' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2)); - ++vPC; + vPC += OPCODE_LENGTH(op_nstricteq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_less) { @@ -1379,14 +1326,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi with the ECMAScript '<' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsBoolean(jsLess(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_less); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_lesseq) { @@ -1396,14 +1343,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register src2, as with the ECMAScript '<=' operator, and puts the result as a boolean in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_lesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pre_inc) { @@ -1412,7 +1359,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register srcDst to number, adds one, and puts the result back in register srcDst. */ - int srcDst = (++vPC)->u.operand; + int srcDst = vPC[1].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() < INT_MAX) callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); @@ -1422,7 +1369,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(srcDst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_pre_inc); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pre_dec) { @@ -1431,7 +1378,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register srcDst to number, subtracts one, and puts the result back in register srcDst. */ - int srcDst = (++vPC)->u.operand; + int srcDst = vPC[1].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() > INT_MIN) callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); @@ -1441,7 +1388,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(srcDst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_pre_dec); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_post_inc) { @@ -1451,8 +1398,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi written to register dst, and the number plus one is written back to register srcDst. */ - int dst = (++vPC)->u.operand; - int srcDst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int srcDst = vPC[2].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() < INT_MAX) { callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1); @@ -1464,7 +1411,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = number; } - ++vPC; + vPC += OPCODE_LENGTH(op_post_inc); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_post_dec) { @@ -1474,8 +1421,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi written to register dst, and the number minus one is written back to register srcDst. */ - int dst = (++vPC)->u.operand; - int srcDst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int srcDst = vPC[2].u.operand; JSValue v = callFrame->r(srcDst).jsValue(); if (v.isInt32() && v.asInt32() > INT_MIN) { callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1); @@ -1487,7 +1434,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = number; } - ++vPC; + vPC += OPCODE_LENGTH(op_post_dec); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_to_jsnumber) { @@ -1496,8 +1443,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register src to number, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue srcVal = callFrame->r(src).jsValue(); @@ -1509,7 +1456,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_to_jsnumber); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_negate) { @@ -1518,8 +1465,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Converts register src to number, negates it, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isInt32() && src.asInt32()) callFrame->r(dst) = jsNumber(callFrame, -src.asInt32()); else { @@ -1528,7 +1475,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_negate); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_add) { @@ -1538,9 +1485,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. (JS add may be string concatenation or numeric add, depending on the types of the operands.) */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32()); else { @@ -1548,7 +1495,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_add); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mul) { @@ -1557,9 +1504,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Multiplies register src1 and register src2 (converted to numbers), and puts the product in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32()); else { @@ -1568,7 +1515,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_mul); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_div) { @@ -1578,15 +1525,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register divisor (converted to number), and puts the quotient in register dst. */ - int dst = (++vPC)->u.operand; - JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - vPC += 2; + vPC += OPCODE_LENGTH(op_div); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mod) { @@ -1596,15 +1543,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register divisor (converted to number), and puts the remainder in register dst. */ - int dst = (++vPC)->u.operand; - JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) { JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32()); ASSERT(result); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_mod); NEXT_INSTRUCTION(); } @@ -1615,7 +1562,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi JSValue result = jsNumber(callFrame, fmod(d1, d2)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_mod); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_sub) { @@ -1625,9 +1572,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi src1 (converted to number), and puts the difference in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32()); else { @@ -1635,7 +1582,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_sub); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_lshift) { @@ -1645,9 +1592,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f)); @@ -1657,7 +1604,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_lshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_rshift) { @@ -1667,9 +1614,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi to int32) by register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); @@ -1679,7 +1626,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_rshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_urshift) { @@ -1689,9 +1636,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi to uint32) by register shift (converted to uint32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue val = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue shift = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); if (val.isUInt32() && shift.isInt32()) callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f)); else { @@ -1700,7 +1647,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_urshift); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitand) { @@ -1710,9 +1657,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32()); else { @@ -1721,7 +1668,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitand); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitxor) { @@ -1731,9 +1678,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32()); else { @@ -1742,7 +1689,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitxor); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitor) { @@ -1752,9 +1699,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and register src2 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); if (src1.isInt32() && src2.isInt32()) callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32()); else { @@ -1763,7 +1710,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = result; } - vPC += 2; + vPC += OPCODE_LENGTH(op_bitor); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitnot) { @@ -1772,8 +1719,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Computes bitwise NOT of register src1 (converted to int32), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - JSValue src = callFrame->r((++vPC)->u.operand).jsValue(); + int dst = vPC[1].u.operand; + JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); if (src.isInt32()) callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32()); else { @@ -1781,7 +1728,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; } - ++vPC; + vPC += OPCODE_LENGTH(op_bitnot); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_not) { @@ -1790,13 +1737,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Computes logical NOT of register src (converted to boolean), and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_not); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_instanceof) { @@ -1826,7 +1773,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = jsBoolean(result); - vPC += 5; + vPC += OPCODE_LENGTH(op_instanceof); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_typeof) { @@ -1835,11 +1782,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Determines the type string for src according to ECMAScript rules, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_typeof); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_undefined) { @@ -1849,12 +1796,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "undefined", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; JSValue v = callFrame->r(src).jsValue(); callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_undefined); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_boolean) { @@ -1864,11 +1811,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "boolean", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_boolean); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_number) { @@ -1878,11 +1825,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "number", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_number); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_string) { @@ -1892,11 +1839,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "string", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString()); - ++vPC; + vPC += OPCODE_LENGTH(op_is_string); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_object) { @@ -1906,11 +1853,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "object", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_is_object); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_is_function) { @@ -1920,11 +1867,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi the ECMAScript rules is "function", and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_is_function); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_in) { @@ -1936,9 +1883,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Raises an exception if register constructor is not an object. */ - int dst = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int base = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int property = vPC[2].u.operand; + int base = vPC[3].u.operand; JSValue baseVal = callFrame->r(base).jsValue(); if (isInvalidParamForIn(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue)) @@ -1957,7 +1904,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property)); } - ++vPC; + vPC += OPCODE_LENGTH(op_in); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve) { @@ -1970,7 +1917,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 3; + vPC += OPCODE_LENGTH(op_resolve); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_skip) { @@ -1983,7 +1930,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 4; + vPC += OPCODE_LENGTH(op_resolve_skip); NEXT_INSTRUCTION(); } @@ -1998,7 +1945,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 6; + vPC += OPCODE_LENGTH(op_resolve_global); NEXT_INSTRUCTION(); } @@ -2007,13 +1954,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Gets the global var at global slot index and places it in register dst. */ - int dst = (++vPC)->u.operand; - JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); + int dst = vPC[1].u.operand; + JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); ASSERT(scope->isGlobalObject()); - int index = (++vPC)->u.operand; + int index = vPC[3].u.operand; callFrame->r(dst) = scope->registerAt(index); - ++vPC; + vPC += OPCODE_LENGTH(op_get_global_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_global_var) { @@ -2021,13 +1968,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Puts value into global slot index. */ - JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); + JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[1].u.jsCell); ASSERT(scope->isGlobalObject()); - int index = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int index = vPC[2].u.operand; + int value = vPC[3].u.operand; scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_global_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_scoped_var) { @@ -2036,9 +1983,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Loads the contents of the index-th local from the scope skip nodes from the top of the scope chain, and places it in register dst */ - int dst = (++vPC)->u.operand; - int index = (++vPC)->u.operand; - int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain(); + int dst = vPC[1].u.operand; + int index = vPC[2].u.operand; + int skip = vPC[3].u.operand + callFrame->codeBlock()->needsFullScopeChain(); ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -2052,16 +1999,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); callFrame->r(dst) = scope->registerAt(index); - ++vPC; + vPC += OPCODE_LENGTH(op_get_scoped_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_scoped_var) { /* put_scoped_var index(n) skip(n) value(r) */ - int index = (++vPC)->u.operand; - int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain(); - int value = (++vPC)->u.operand; + int index = vPC[1].u.operand; + int skip = vPC[2].u.operand + callFrame->codeBlock()->needsFullScopeChain(); + int value = vPC[3].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -2075,7 +2022,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT((*iter)->isVariableObject()); JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_scoped_var); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_base) { @@ -2088,7 +2035,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ resolveBase(callFrame, vPC); - vPC += 3; + vPC += OPCODE_LENGTH(op_resolve_base); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_resolve_with_base) { @@ -2106,7 +2053,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue))) goto vm_throw; - vPC += 4; + vPC += OPCODE_LENGTH(op_resolve_with_base); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id) { @@ -2129,7 +2076,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot); callFrame->r(dst) = result; - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_self) { @@ -2155,7 +2102,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_self); NEXT_INSTRUCTION(); } } @@ -2189,7 +2136,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_proto); NEXT_INSTRUCTION(); } } @@ -2202,14 +2149,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi // Polymorphic self access caching currently only supported when JITting. ASSERT_NOT_REACHED(); // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_self_list); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_proto_list) { // Polymorphic prototype access caching currently only supported when JITting. ASSERT_NOT_REACHED(); // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_proto_list); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_id_chain) { @@ -2244,7 +2191,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset)); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_chain); NEXT_INSTRUCTION(); } @@ -2274,7 +2221,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - vPC += 8; + vPC += OPCODE_LENGTH(op_get_by_id_generic); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_array_length) { @@ -2290,7 +2237,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (LIKELY(isJSArray(globalData, baseValue))) { int dst = vPC[1].u.operand; callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length()); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_array_length); NEXT_INSTRUCTION(); } @@ -2310,7 +2257,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (LIKELY(isJSString(globalData, baseValue))) { int dst = vPC[1].u.operand; callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size()); - vPC += 8; + vPC += OPCODE_LENGTH(op_get_string_length); NEXT_INSTRUCTION(); } @@ -2340,7 +2287,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_id_transition) { @@ -2385,7 +2332,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_transition); NEXT_INSTRUCTION(); } } @@ -2420,7 +2367,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset); baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_replace); NEXT_INSTRUCTION(); } } @@ -2447,7 +2394,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); CHECK_FOR_EXCEPTION(); - vPC += 8; + vPC += OPCODE_LENGTH(op_put_by_id_generic); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_del_by_id) { @@ -2458,16 +2405,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi boolean indicating success (if true) or failure (if false) to register dst. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); Identifier& ident = callFrame->codeBlock()->identifier(property); JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_del_by_id); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_val) { @@ -2478,9 +2425,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi in register dst. property is nominally converted to string but numbers are treated more efficiently. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSValue baseValue = callFrame->r(base).jsValue(); JSValue subscript = callFrame->r(property).jsValue(); @@ -2508,7 +2455,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_get_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_val) { @@ -2522,9 +2469,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int value = vPC[3].u.operand; JSValue baseValue = callFrame->r(base).jsValue(); JSValue subscript = callFrame->r(property).jsValue(); @@ -2558,7 +2505,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); - ++vPC; + vPC += OPCODE_LENGTH(op_put_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_del_by_val) { @@ -2569,9 +2516,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi boolean indicating success (if true) or failure (if false) to register dst. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw @@ -2589,7 +2536,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_del_by_val); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_by_index) { @@ -2604,13 +2551,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi This opcode is mainly used to initialize array literals. */ - int base = (++vPC)->u.operand; - unsigned property = (++vPC)->u.operand; - int value = (++vPC)->u.operand; + int base = vPC[1].u.operand; + unsigned property = vPC[2].u.operand; + int value = vPC[3].u.operand; callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue()); - ++vPC; + vPC += OPCODE_LENGTH(op_put_by_index); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop) { @@ -2625,7 +2572,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi #if ENABLE(OPCODE_STATS) OpcodeStats::resetLastInstruction(); #endif - int target = (++vPC)->u.operand; + int target = vPC[1].u.operand; CHECK_FOR_TIMEOUT(); vPC += target; NEXT_INSTRUCTION(); @@ -2639,7 +2586,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi #if ENABLE(OPCODE_STATS) OpcodeStats::resetLastInstruction(); #endif - int target = (++vPC)->u.operand; + int target = vPC[1].u.operand; vPC += target; NEXT_INSTRUCTION(); @@ -2653,15 +2600,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; CHECK_FOR_TIMEOUT(); NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_true); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jtrue) { @@ -2670,14 +2617,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register cond converts to boolean as true. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jtrue); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jfalse) { @@ -2686,14 +2633,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register cond converts to boolean as false. */ - int cond = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int cond = vPC[1].u.operand; + int target = vPC[2].u.operand; if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jfalse); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jeq_null) { @@ -2702,8 +2649,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register src is null. */ - int src = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + int target = vPC[2].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { @@ -2711,7 +2658,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jeq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jneq_null) { @@ -2720,8 +2667,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if and only if register src is not null. */ - int src = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + int target = vPC[2].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { @@ -2729,7 +2676,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jneq_null); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jneq_ptr) { @@ -2738,16 +2685,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Jumps to offset target from the current instruction, if the value r is equal to ptr, using pointer equality. */ - int src = (++vPC)->u.operand; - JSValue ptr = JSValue((++vPC)->u.jsCell); - int target = (++vPC)->u.operand; + int src = vPC[1].u.operand; + JSValue ptr = JSValue(vPC[2].u.jsCell); + int target = vPC[3].u.operand; JSValue srcValue = callFrame->r(src).jsValue(); if (srcValue != ptr) { vPC += target; NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jneq_ptr); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop_if_less) { @@ -2761,9 +2708,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2774,7 +2721,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_less); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_loop_if_lesseq) { @@ -2788,9 +2735,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Additionally this loop instruction may terminate JS execution is the JS timeout is reached. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLessEq(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2801,7 +2748,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_loop_if_lesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jnless) { @@ -2812,9 +2759,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi target from the current instruction, if and only if the result of the comparison is false. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2824,7 +2771,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jnless); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jnlesseq) { @@ -2835,9 +2782,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi and then jumps to offset target from the current instruction, if and only if theresult of the comparison is false. */ - JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue(); - JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue(); - int target = (++vPC)->u.operand; + JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); + JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); + int target = vPC[3].u.operand; bool result = jsLessEq(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2847,7 +2794,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jnlesseq); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_switch_imm) { @@ -2859,9 +2806,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi table, and the value at jumpTable[scrutinee value] is non-zero, then that value is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (scrutinee.isInt32()) vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); else { @@ -2883,9 +2830,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi table, and the value at jumpTable[scrutinee value] is non-zero, then that value is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else { @@ -2906,9 +2853,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi jump table, then the value associated with the string is used as the jump offset, otherwise defaultOffset is used. */ - int tableIndex = (++vPC)->u.operand; - int defaultOffset = (++vPC)->u.operand; - JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue(); + int tableIndex = vPC[1].u.operand; + int defaultOffset = vPC[2].u.operand; + JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); if (!scrutinee.isString()) vPC += defaultOffset; else @@ -2923,12 +2870,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor, using the rules for function declarations, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int func = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int func = vPC[2].u.operand; callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain())); - ++vPC; + vPC += OPCODE_LENGTH(op_new_func); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_func_exp) { @@ -2939,8 +2886,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constructor, using the rules for function expressions, and puts the result in register dst. */ - int dst = (++vPC)->u.operand; - int funcIndex = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int funcIndex = vPC[2].u.operand; FunctionExecutable* function = callFrame->codeBlock()->functionExpr(funcIndex); JSFunction* func = function->make(callFrame, callFrame->scopeChain()); @@ -2959,7 +2906,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = JSValue(func); - ++vPC; + vPC += OPCODE_LENGTH(op_new_func_exp); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_call_eval) { @@ -2992,7 +2939,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi goto vm_throw; callFrame->r(dst) = result; - vPC += 5; + vPC += OPCODE_LENGTH(op_call_eval); NEXT_INSTRUCTION(); } @@ -3066,7 +3013,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call); NEXT_INSTRUCTION(); } @@ -3076,8 +3023,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi goto vm_throw; } DEFINE_OPCODE(op_load_varargs) { - int argCountDst = (++vPC)->u.operand; - int argsOffset = (++vPC)->u.operand; + int argCountDst = vPC[1].u.operand; + int argsOffset = vPC[2].u.operand; JSValue arguments = callFrame->r(argsOffset).jsValue(); int32_t argCount = 0; @@ -3149,7 +3096,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi } CHECK_FOR_EXCEPTION(); callFrame->r(argCountDst) = Register::withInt(argCount + 1); - ++vPC; + vPC += OPCODE_LENGTH(op_load_varargs); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_call_varargs) { @@ -3220,7 +3167,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call_varargs); NEXT_INSTRUCTION(); } @@ -3242,12 +3189,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi This opcode should only be used immediately before op_ret. */ - int src = (++vPC)->u.operand; + int src = vPC[1].u.operand; ASSERT(callFrame->codeBlock()->needsFullScopeChain()); asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments()); - ++vPC; + vPC += OPCODE_LENGTH(op_tear_off_activation); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_tear_off_arguments) { @@ -3268,7 +3215,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (callFrame->optionalCalleeArguments()) callFrame->optionalCalleeArguments()->copyRegisters(); - ++vPC; + vPC += OPCODE_LENGTH(op_tear_off_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_ret) { @@ -3281,7 +3228,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi register base to those of the calling function. */ - int result = (++vPC)->u.operand; + int result = vPC[1].u.operand; if (callFrame->codeBlock()->needsFullScopeChain()) callFrame->scopeChain()->deref(); @@ -3316,7 +3263,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi for (size_t count = codeBlock->m_numVars; i < count; ++i) callFrame->r(i) = jsUndefined(); - ++vPC; + vPC += OPCODE_LENGTH(op_enter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_enter_with_activation) { @@ -3338,12 +3285,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi for (size_t count = codeBlock->m_numVars; i < count; ++i) callFrame->r(i) = jsUndefined(); - int dst = (++vPC)->u.operand; + int dst = vPC[1].u.operand; JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable())); callFrame->r(dst) = JSValue(activation); callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); - ++vPC; + vPC += OPCODE_LENGTH(op_enter_with_activation); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_convert_this) { @@ -3358,12 +3305,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi block. */ - int thisRegister = (++vPC)->u.operand; + int thisRegister = vPC[1].u.operand; JSValue thisVal = callFrame->r(thisRegister).jsValue(); if (thisVal.needsThisConversion()) callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); - ++vPC; + vPC += OPCODE_LENGTH(op_convert_this); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_init_arguments) { @@ -3377,7 +3324,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi block. */ callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(); - ++vPC; + vPC += OPCODE_LENGTH(op_init_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_create_arguments) { @@ -3393,7 +3340,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->setCalleeArguments(arguments); callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments); } - ++vPC; + vPC += OPCODE_LENGTH(op_create_arguments); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_construct) { @@ -3471,7 +3418,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi CHECK_FOR_EXCEPTION(); callFrame->r(dst) = JSValue(returnValue); - vPC += 7; + vPC += OPCODE_LENGTH(op_construct); NEXT_INSTRUCTION(); } @@ -3489,32 +3436,32 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi int dst = vPC[1].u.operand; if (LIKELY(callFrame->r(dst).jsValue().isObject())) { - vPC += 3; + vPC += OPCODE_LENGTH(op_construct_verify); NEXT_INSTRUCTION(); } int override = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(override); - vPC += 3; + vPC += OPCODE_LENGTH(op_construct_verify); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_strcat) { - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; - int count = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; + int count = vPC[3].u.operand; callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count); - ++vPC; + vPC += OPCODE_LENGTH(op_strcat); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_to_primitive) { - int dst = (++vPC)->u.operand; - int src = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int src = vPC[2].u.operand; callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame); - ++vPC; + vPC += OPCODE_LENGTH(op_to_primitive); NEXT_INSTRUCTION(); } @@ -3525,7 +3472,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi of the current scope chain. The contents of the register scope are replaced by the result of toObject conversion of the scope. */ - int scope = (++vPC)->u.operand; + int scope = vPC[1].u.operand; JSValue v = callFrame->r(scope).jsValue(); JSObject* o = v.toObject(callFrame); CHECK_FOR_EXCEPTION(); @@ -3533,7 +3480,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(scope) = JSValue(o); callFrame->setScopeChain(callFrame->scopeChain()->push(o)); - ++vPC; + vPC += OPCODE_LENGTH(op_push_scope); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_pop_scope) { @@ -3543,47 +3490,69 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ callFrame->setScopeChain(callFrame->scopeChain()->pop()); - ++vPC; + vPC += OPCODE_LENGTH(op_pop_scope); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_pnames) { - /* get_pnames dst(r) base(r) + /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset) Creates a property name list for register base and puts it - in register dst. This is not a true JavaScript value, just - a synthetic value used to keep the iteration state in a - register. + in register dst, initializing i and size for iteration. If + base is undefined or null, jumps to breakTarget. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int breakTarget = vPC[5].u.operand; + + JSValue v = callFrame->r(base).jsValue(); + if (v.isUndefinedOrNull()) { + vPC += breakTarget; + NEXT_INSTRUCTION(); + } + + JSObject* o = v.toObject(callFrame); + Structure* structure = o->structure(); + JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); + if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) + jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); - callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue()); - ++vPC; + callFrame->r(dst) = jsPropertyNameIterator; + callFrame->r(base) = JSValue(o); + callFrame->r(i) = Register::withInt(0); + callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size()); + vPC += OPCODE_LENGTH(op_get_pnames); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_next_pname) { - /* next_pname dst(r) iter(r) target(offset) + /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) - Tries to copies the next name from property name list in - register iter. If there are names left, then copies one to - register dst, and jumps to offset target. If there are none - left, invalidates the iterator and continues to the next + Copies the next name from the property name list in + register iter to dst, then jumps to offset target. If there are no + names left, invalidates the iterator and continues to the next instruction. */ - int dst = (++vPC)->u.operand; - int iter = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int iter = vPC[5].u.operand; + int target = vPC[6].u.operand; JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); - if (JSValue temp = it->next(callFrame)) { - CHECK_FOR_TIMEOUT(); - callFrame->r(dst) = JSValue(temp); - vPC += target; - NEXT_INSTRUCTION(); + while (callFrame->r(i).i() != callFrame->r(size).i()) { + JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); + callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1); + if (key) { + CHECK_FOR_TIMEOUT(); + callFrame->r(dst) = key; + vPC += target; + NEXT_INSTRUCTION(); + } } - it->invalidate(); - ++vPC; + vPC += OPCODE_LENGTH(op_next_pname); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jmp_scopes) { @@ -3593,8 +3562,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi specified by immediate number count, then jumps to offset target. */ - int count = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int count = vPC[1].u.operand; + int target = vPC[2].u.operand; ScopeChainNode* tmp = callFrame->scopeChain(); while (count--) @@ -3617,7 +3586,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ callFrame->setScopeChain(createExceptionScope(callFrame, vPC)); - vPC += 4; + vPC += OPCODE_LENGTH(op_push_new_scope); NEXT_INSTRUCTION(); } #if HAVE(COMPUTED_GOTO) @@ -3632,11 +3601,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ ASSERT(exceptionValue); ASSERT(!globalData->exception); - int ex = (++vPC)->u.operand; + int ex = vPC[1].u.operand; callFrame->r(ex) = exceptionValue; exceptionValue = JSValue(); - ++vPC; + vPC += OPCODE_LENGTH(op_catch); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_throw) { @@ -3650,7 +3619,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi else the script returns control to the nearest native caller. */ - int ex = (++vPC)->u.operand; + int ex = vPC[1].u.operand; exceptionValue = callFrame->r(ex).jsValue(); handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true); @@ -3670,14 +3639,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi constant message as the message string. The result is written to register dst. */ - int dst = (++vPC)->u.operand; - int type = (++vPC)->u.operand; - int message = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int type = vPC[2].u.operand; + int message = vPC[3].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL())); - ++vPC; + vPC += OPCODE_LENGTH(op_new_error); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_end) { @@ -3692,7 +3661,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(scopeChain->refCount > 1); scopeChain->deref(); } - int result = (++vPC)->u.operand; + int result = vPC[1].u.operand; return callFrame->r(result).jsValue(); } DEFINE_OPCODE(op_put_getter) { @@ -3706,9 +3675,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int function = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int function = vPC[3].u.operand; ASSERT(callFrame->r(base).jsValue().isObject()); JSObject* baseObj = asObject(callFrame->r(base).jsValue()); @@ -3716,7 +3685,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(callFrame->r(function).jsValue().isObject()); baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); - ++vPC; + vPC += OPCODE_LENGTH(op_put_getter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_put_setter) { @@ -3730,9 +3699,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Unlike many opcodes, this one does not write any output to the register file. */ - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; - int function = (++vPC)->u.operand; + int base = vPC[1].u.operand; + int property = vPC[2].u.operand; + int function = vPC[3].u.operand; ASSERT(callFrame->r(base).jsValue().isObject()); JSObject* baseObj = asObject(callFrame->r(base).jsValue()); @@ -3740,7 +3709,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi ASSERT(callFrame->r(function).jsValue().isObject()); baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); - ++vPC; + vPC += OPCODE_LENGTH(op_put_setter); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_method_check) { @@ -3753,9 +3722,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Places the address of the next instruction into the retAddrDst register and jumps to offset target from the current instruction. */ - int retAddrDst = (++vPC)->u.operand; - int target = (++vPC)->u.operand; - callFrame->r(retAddrDst) = vPC + 1; + int retAddrDst = vPC[1].u.operand; + int target = vPC[2].u.operand; + callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr); vPC += target; NEXT_INSTRUCTION(); @@ -3767,7 +3736,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi differs from op_jmp because the target address is stored in a register, not as an immediate. */ - int retAddrSrc = (++vPC)->u.operand; + int retAddrSrc = vPC[1].u.operand; vPC = callFrame->r(retAddrSrc).vPC(); NEXT_INSTRUCTION(); } @@ -3777,13 +3746,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Notifies the debugger of the current state of execution. This opcode is only generated while the debugger is attached. */ - int debugHookID = (++vPC)->u.operand; - int firstLine = (++vPC)->u.operand; - int lastLine = (++vPC)->u.operand; + int debugHookID = vPC[1].u.operand; + int firstLine = vPC[2].u.operand; + int lastLine = vPC[3].u.operand; debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine); - ++vPC; + vPC += OPCODE_LENGTH(op_debug); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_profile_will_call) { @@ -3797,7 +3766,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (*enabledProfilerReference) (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue()); - vPC += 2; + vPC += OPCODE_LENGTH(op_profile_will_call); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_profile_did_call) { @@ -3811,7 +3780,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi if (*enabledProfilerReference) (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue()); - vPC += 2; + vPC += OPCODE_LENGTH(op_profile_did_call); NEXT_INSTRUCTION(); } vm_throw: { diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h index 3046b28..e17b055 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.h @@ -129,7 +129,6 @@ namespace JSC { NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue); NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC); NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue); - NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue& exceptionValue); NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC); void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 3274fcc..1d15ef0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -78,6 +78,9 @@ private: struct Allocation { char* pages; size_t size; +#if PLATFORM(SYMBIAN) + RChunk* chunk; +#endif }; typedef Vector<Allocation, 2> AllocationList; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp new file mode 100644 index 0000000..c96ecae --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + */ + +#include "config.h" + +#include "ExecutableAllocator.h" + +#if ENABLE(ASSEMBLER) && PLATFORM(SYMBIAN) + +#include <e32hal.h> +#include <e32std.h> + +// Set the page size to 256 Kb to compensate for moving memory model limitation +const size_t MOVING_MEM_PAGE_SIZE = 256 * 1024; + +namespace JSC { + +void ExecutableAllocator::intializePageSize() +{ +#if PLATFORM_ARM_ARCH(5) + // The moving memory model (as used in ARMv5 and earlier platforms) + // on Symbian OS limits the number of chunks for each process to 16. + // To mitigate this limitation increase the pagesize to + // allocate less of larger chunks. + ExecutableAllocator::pageSize = MOVING_MEM_PAGE_SIZE; +#else + TInt page_size; + UserHal::PageSizeInBytes(page_size); + ExecutableAllocator::pageSize = page_size; +#endif +} + +ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) +{ + RChunk* codeChunk = new RChunk(); + + TInt errorCode = codeChunk->CreateLocalCode(n, n); + + char* allocation = reinterpret_cast<char*>(codeChunk->Base()); + if (!allocation) + CRASH(); + ExecutablePool::Allocation alloc = { allocation, n, codeChunk }; + return alloc; +} + +void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) +{ + alloc.chunk->Close(); + delete alloc.chunk; +} + +#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) +#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." +#endif + +} + +#endif // HAVE(ASSEMBLER) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp index ea8434e..fa0ac2e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp @@ -202,7 +202,6 @@ void JIT::privateCompileMainPass() DEFINE_BINARY_OP(op_less) DEFINE_BINARY_OP(op_lesseq) DEFINE_BINARY_OP(op_urshift) - DEFINE_UNARY_OP(op_get_pnames) DEFINE_UNARY_OP(op_is_boolean) DEFINE_UNARY_OP(op_is_function) DEFINE_UNARY_OP(op_is_number) @@ -241,6 +240,7 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_get_by_id) DEFINE_OP(op_get_by_val) DEFINE_OP(op_get_global_var) + DEFINE_OP(op_get_pnames) DEFINE_OP(op_get_scoped_var) DEFINE_OP(op_instanceof) DEFINE_OP(op_jeq_null) @@ -489,21 +489,21 @@ JITCode JIT::privateCompile() ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character); ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size()); - record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) { unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j]; - record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; + record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; } } else { ASSERT(record.type == SwitchRecord::String); - record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end(); for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) { unsigned offset = it->second.branchOffset; - it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault; + it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.stringJumpTable->ctiDefault; } } } diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h index 0712743..9406d1f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h @@ -386,6 +386,8 @@ namespace JSC { Address addressFor(unsigned index, RegisterID base = callFrameRegister); + void testPrototype(Structure*, JumpList& failureCases); + #if USE(JSVALUE32_64) Address tagFor(unsigned index, RegisterID base = callFrameRegister); Address payloadFor(unsigned index, RegisterID base = callFrameRegister); @@ -713,6 +715,7 @@ namespace JSC { void emit_op_new_func_exp(Instruction*); void emit_op_new_object(Instruction*); void emit_op_new_regexp(Instruction*); + void emit_op_get_pnames(Instruction*); void emit_op_next_pname(Instruction*); void emit_op_not(Instruction*); void emit_op_nstricteq(Instruction*); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp index 7afc1f2..8cda482 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITArithmetic.cpp @@ -98,16 +98,16 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT3, regT2); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target); } else if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); } else { emitLoad2(op1, regT1, regT0, op2, regT3, regT2); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, regT2), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, regT2), target); } if (!supportsFloatingPoint()) { @@ -145,7 +145,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } void JIT::emit_op_jnlesseq(Instruction* currentInstruction) @@ -161,16 +161,16 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT3, regT2); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target); } else if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); } else { emitLoad2(op1, regT1, regT0, op2, regT3, regT2); notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, regT2), target + 3); + addJump(branch32(GreaterThan, regT0, regT2), target); } if (!supportsFloatingPoint()) { @@ -208,7 +208,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } // LeftShift (<<) @@ -829,11 +829,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi break; case op_jnless: emitLoadDouble(op1, fpRegT2); - addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst + 3); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst); break; case op_jnlesseq: emitLoadDouble(op1, fpRegT2); - addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst + 3); + addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst); break; default: ASSERT_NOT_REACHED(); @@ -882,11 +882,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi break; case op_jnless: emitLoadDouble(op2, fpRegT1); - addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst + 3); + addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst); break; case op_jnlesseq: emitLoadDouble(op2, fpRegT1); - addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst + 3); + addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst); break; default: ASSERT_NOT_REACHED(); @@ -1313,7 +1313,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -1322,13 +1322,13 @@ void JIT::emit_op_jnless(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target + 3); + addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, regT1), target); } } @@ -1365,7 +1365,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1382,7 +1382,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); @@ -1406,7 +1406,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1423,7 +1423,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else { linkSlowCase(iter); @@ -1452,7 +1452,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); @@ -1475,7 +1475,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } } @@ -1498,7 +1498,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -1507,13 +1507,13 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(LessThan, regT1, Imm32(op1imm)), target + 3); + addJump(branch32(LessThan, regT1, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(GreaterThan, regT0, regT1), target + 3); + addJump(branch32(GreaterThan, regT0, regT1), target); } } @@ -1550,7 +1550,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE move(Imm32(op2imm), regT1); convertInt32ToDouble(regT1, fpRegT1); - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1567,7 +1567,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); @@ -1591,7 +1591,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE move(Imm32(op1imm), regT0); convertInt32ToDouble(regT0, fpRegT0); - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1608,7 +1608,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(op1, regT2); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } else { linkSlowCase(iter); @@ -1637,7 +1637,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1); #endif - emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3); + emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target); emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); @@ -1660,7 +1660,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(Zero, regT0), target); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp index 4fd24d2..cfaa69f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp @@ -236,19 +236,17 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); } - emitLoad(callee, regT1, regT2); + emitLoad(callee, regT1, regT0); if (opcodeID == op_call) compileOpCallSetupArgs(instruction); @@ -256,12 +254,12 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) compileOpConstructSetupArgs(instruction); emitJumpSlowCaseIfNotJSCell(callee, regT1); - addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr))); + addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr))); // First, in the case of a construct, allocate the new object. if (opcodeID == op_construct) { JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount); - emitLoad(callee, regT1, regT2); + emitLoad(callee, regT1, regT0); } // Speculatively roll the callframe, assuming argCount will match the arity. @@ -271,12 +269,10 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); - emitStore(dst, regT1, regT0);; + emitStore(dst, regT1, regT0); sampleCodeBlock(m_codeBlock); } @@ -306,16 +302,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); } emitLoad(callee, regT1, regT0); @@ -359,10 +353,8 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Call to the callee m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); // Put the return value in dst. In the interpreter, op_ret does this. emitStore(dst, regT1, regT0); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp index 7059cc8..e10d105 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp @@ -33,6 +33,7 @@ #include "JSArray.h" #include "JSCell.h" #include "JSFunction.h" +#include "JSPropertyNameIterator.h" #include "LinkBuffer.h" namespace JSC { @@ -248,10 +249,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); // Check for an exception - // FIXME: Maybe we can optimize this comparison to JSValue(). move(ImmPtr(&globalData->exception), regT2); - Jump sawException1 = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::CellTag)); - Jump sawException2 = branch32(NonZero, payloadFor(0, regT2), Imm32(0)); + Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag)); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3); @@ -264,13 +263,12 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable ret(); // Handle an exception - sawException1.link(this); - sawException2.link(this); + sawException.link(this); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); restoreReturnAddressBeforeReturn(regT2); @@ -348,14 +346,14 @@ void JIT::emit_op_end(Instruction* currentInstruction) void JIT::emit_op_jmp(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; emitTimeoutCheck(); - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop_if_less(Instruction* currentInstruction) @@ -369,21 +367,21 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target); return; } if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); return; } emitLoad2(op1, regT1, regT0, op2, regT3, regT2); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, regT2), target + 3); + addJump(branch32(LessThan, regT0, regT2), target); } void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -400,7 +398,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) @@ -414,21 +412,21 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) if (isOperandConstantImmediateInt(op1)) { emitLoad(op2, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3); + addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target); return; } if (isOperandConstantImmediateInt(op2)) { emitLoad(op1, regT1, regT0); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3); + addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); return; } emitLoad2(op1, regT1, regT0, op2, regT3, regT2); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThanOrEqual, regT0, regT2), target + 3); + addJump(branch32(LessThanOrEqual, regT0, regT2), target); } void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -445,7 +443,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(op1); stubCall.addArgument(op2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_new_object(Instruction* currentInstruction) @@ -460,30 +458,20 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) unsigned baseVal = currentInstruction[3].u.operand; unsigned proto = currentInstruction[4].u.operand; - // Load the operands (baseVal, proto, and value respectively) into registers. + // Load the operands into registers. // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. - emitLoadPayload(proto, regT1); - emitLoadPayload(baseVal, regT0); emitLoadPayload(value, regT2); + emitLoadPayload(baseVal, regT0); + emitLoadPayload(proto, regT1); - // Check that baseVal & proto are cells. - emitJumpSlowCaseIfNotJSCell(proto); + // Check that value, baseVal, and proto are cells. + emitJumpSlowCaseIfNotJSCell(value); emitJumpSlowCaseIfNotJSCell(baseVal); + emitJumpSlowCaseIfNotJSCell(proto); - // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + // Check that baseVal 'ImplementsDefaultHasInstance'. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); // FIXME: Maybe remove this test. - addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance))); // FIXME: TOT checks ImplementsDefaultHasInstance. - - // If value is not an Object, return false. - emitLoadTag(value, regT0); - Jump valueIsImmediate = branch32(NotEqual, regT0, Imm32(JSValue::CellTag)); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); // FIXME: Maybe remove this test. - - // Check proto is object. - loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance))); // Optimistically load the result true, and start looping. // Initially, regT1 still contains proto and regT2 still contains value. @@ -491,16 +479,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) move(Imm32(JSValue::TrueTag), regT0); Label loop(this); - // Load the prototype of the object in regT2. If this is equal to regT1 - WIN! + // Load the prototype of the cell in regT2. If this is equal to regT1 - WIN! // Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again. loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2); Jump isInstance = branchPtr(Equal, regT2, regT1); - branch32(NotEqual, regT2, Imm32(0), loop); + branchTest32(NonZero, regT2).linkTo(loop, this); // We get here either by dropping out of the loop, or if value was not an Object. Result is false. - valueIsImmediate.link(this); - valueIsNotObject.link(this); move(Imm32(JSValue::FalseTag), regT0); // isInstance jumps right down to here, to skip setting the result to false (it has already set true). @@ -515,11 +501,10 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas unsigned baseVal = currentInstruction[3].u.operand; unsigned proto = currentInstruction[4].u.operand; + linkSlowCaseIfNotJSCell(iter, value); linkSlowCaseIfNotJSCell(iter, baseVal); linkSlowCaseIfNotJSCell(iter, proto); linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); JITStubCall stubCall(this, cti_op_instanceof); stubCall.addArgument(value); @@ -674,12 +659,12 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); - addJump(branch32(NotEqual, regT0, Imm32(0)), target + 2); + addJump(branch32(NotEqual, regT0, Imm32(0)), target); Jump isNotZero = jump(); isNotInteger.link(this); - addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target); addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag))); isNotZero.link(this); @@ -695,7 +680,7 @@ void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowC JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_resolve_base(Instruction* currentInstruction) @@ -788,11 +773,11 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag)); - addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0)); - addJump(jump(), target + 2); + addJump(jump(), target); if (supportsFloatingPoint()) { isNotInteger.link(this); @@ -801,7 +786,7 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) zeroDouble(fpRegT0); emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2); + addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target); } else addSlowCase(isNotInteger); @@ -818,7 +803,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // Inverted. + emitJumpSlowToHot(branchTest32(Zero, regT0), target); // Inverted. } void JIT::emit_op_jtrue(Instruction* currentInstruction) @@ -829,11 +814,11 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) emitLoad(cond, regT1, regT0); Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag)); - addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2); + addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target); Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); Jump isFalse2 = branch32(Equal, regT0, Imm32(0)); - addJump(jump(), target + 2); + addJump(jump(), target); if (supportsFloatingPoint()) { isNotInteger.link(this); @@ -842,7 +827,7 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) zeroDouble(fpRegT0); emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2); + addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target); } else addSlowCase(isNotInteger); @@ -859,7 +844,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(cond); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } void JIT::emit_op_jeq_null(Instruction* currentInstruction) @@ -873,7 +858,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); @@ -884,7 +869,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); or32(regT2, regT1); - addJump(branchTest32(NonZero, regT1), target + 2); + addJump(branchTest32(NonZero, regT1), target); wasNotImmediate.link(this); } @@ -900,7 +885,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); @@ -911,7 +896,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); or32(regT2, regT1); - addJump(branchTest32(Zero, regT1), target + 2); + addJump(branchTest32(Zero, regT1), target); wasNotImmediate.link(this); } @@ -923,8 +908,8 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) unsigned target = currentInstruction[3].u.operand; emitLoad(src, regT1, regT0); - addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target + 3); - addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target + 3); + addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target); + addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target); } void JIT::emit_op_jsr(Instruction* currentInstruction) @@ -932,7 +917,7 @@ void JIT::emit_op_jsr(Instruction* currentInstruction) int retAddrDst = currentInstruction[1].u.operand; int target = currentInstruction[2].u.operand; DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst)); - addJump(jump(), target + 2); + addJump(jump(), target); m_jsrSites.append(JSRInfo(storeLocation, label())); } @@ -1198,23 +1183,109 @@ void JIT::emit_op_throw(Instruction* currentInstruction) #endif } +void JIT::emit_op_get_pnames(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int breakTarget = currentInstruction[5].u.operand; + + JumpList isNotObject; + + emitLoad(base, regT1, regT0); + if (!m_codeBlock->isKnownNotImmediate(base)) + isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); + if (base != m_codeBlock->thisRegister()) { + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + } + + // We could inline the case where you have a valid cache, but + // this call doesn't seem to be hot. + Label isObject(this); + JITStubCall getPnamesStubCall(this, cti_op_get_pnames); + getPnamesStubCall.addArgument(regT0); + getPnamesStubCall.call(dst); + load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3); + store32(Imm32(0), addressFor(i)); + store32(regT3, addressFor(size)); + Jump end = jump(); + + isNotObject.link(this); + addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget); + addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget); + JITStubCall toObjectStubCall(this, cti_to_object); + toObjectStubCall.addArgument(regT1, regT0); + toObjectStubCall.call(base); + jump().linkTo(isObject, this); + + end.link(this); +} + void JIT::emit_op_next_pname(Instruction* currentInstruction) { int dst = currentInstruction[1].u.operand; - int iter = currentInstruction[2].u.operand; - int target = currentInstruction[3].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int it = currentInstruction[5].u.operand; + int target = currentInstruction[6].u.operand; + + JumpList callHasProperty; + + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); + + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + load32(BaseIndex(regT2, regT0, TimesEight), regT2); + store32(Imm32(JSValue::CellTag), tagFor(dst)); + store32(regT2, payloadFor(dst)); - load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0); + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + loadPtr(addressFor(base), regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); - JITStubCall stubCall(this, cti_op_next_pname); + // Test base's prototype chain + loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3); + loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3); + addJump(branchTestPtr(Zero, Address(regT3)), target); + + Label checkPrototype(this); + callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag))); + loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3))); + addPtr(Imm32(sizeof(Structure*)), regT3); + branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this); + + // Continue loop. + addJump(jump(), target); + + // Slow case: Ask the object if i is valid. + callHasProperty.link(this); + loadPtr(addressFor(dst), regT1); + JITStubCall stubCall(this, cti_has_property); stubCall.addArgument(regT0); + stubCall.addArgument(regT1); stubCall.call(); - Jump endOfIter = branchTestPtr(Zero, regT0); - emitStore(dst, regT1, regT0); - map(m_bytecodeIndex + OPCODE_LENGTH(op_next_pname), dst, regT1, regT0); - addJump(jump(), target + 3); - endOfIter.link(this); + // Test for valid key. + addJump(branchTest32(NonZero, regT0), target); + jump().linkTo(begin, this); + + // End of loop. + end.link(this); } void JIT::emit_op_push_scope(Instruction* currentInstruction) @@ -1237,7 +1308,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction) emitLoad(src, regT1, regT0); Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag)); - addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag))); + addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::EmptyValueTag))); isInt32.link(this); if (src != dst) @@ -1284,7 +1355,7 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); - addJump(jump(), currentInstruction[2].u.operand + 2); + addJump(jump(), currentInstruction[2].u.operand); } void JIT::emit_op_switch_imm(Instruction* currentInstruction) @@ -1381,8 +1452,7 @@ void JIT::emit_op_enter_with_activation(Instruction* currentInstruction) void JIT::emit_op_create_arguments(Instruction*) { - Jump argsNotCell = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::CellTag)); - Jump argsNotNull = branchTestPtr(NonZero, payloadFor(RegisterFile::ArgumentsRegister, callFrameRegister)); + Jump argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag)); // If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation. if (m_codeBlock->m_numParameters == 1) @@ -1390,8 +1460,7 @@ void JIT::emit_op_create_arguments(Instruction*) else JITStubCall(this, cti_op_create_arguments).call(); - argsNotCell.link(this); - argsNotNull.link(this); + argsCreated.link(this); } void JIT::emit_op_init_arguments(Instruction*) @@ -1754,7 +1823,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); restoreReturnAddressBeforeReturn(regT2); @@ -1830,8 +1899,8 @@ void JIT::emit_op_end(Instruction* currentInstruction) void JIT::emit_op_jmp(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); - RECORD_JUMP_TARGET(target + 1); + addJump(jump(), target); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_loop(Instruction* currentInstruction) @@ -1839,7 +1908,7 @@ void JIT::emit_op_loop(Instruction* currentInstruction) emitTimeoutCheck(); unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop_if_less(Instruction* currentInstruction) @@ -1857,7 +1926,7 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThan, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); @@ -1866,12 +1935,12 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThan, regT0, regT1), target + 3); + addJump(branch32(LessThan, regT0, regT1), target); } } @@ -1890,12 +1959,12 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3); + addJump(branch32(LessThanOrEqual, regT0, regT1), target); } } @@ -1906,30 +1975,26 @@ void JIT::emit_op_new_object(Instruction* currentInstruction) void JIT::emit_op_instanceof(Instruction* currentInstruction) { + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + // Load the operands (baseVal, proto, and value respectively) into registers. // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); - emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); - emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); + emitGetVirtualRegister(value, regT2); + emitGetVirtualRegister(baseVal, regT0); + emitGetVirtualRegister(proto, regT1); // Check that baseVal & proto are cells. - emitJumpSlowCaseIfNotJSCell(regT0); - emitJumpSlowCaseIfNotJSCell(regT1); + emitJumpSlowCaseIfNotJSCell(regT2, value); + emitJumpSlowCaseIfNotJSCell(regT0, baseVal); + emitJumpSlowCaseIfNotJSCell(regT1, proto); - // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + // Check that baseVal 'ImplementsDefaultHasInstance'. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance))); - // If value is not an Object, return false. - Jump valueIsImmediate = emitJumpIfNotJSCell(regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); - - // Check proto is object. - loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); - // Optimistically load the result true, and start looping. // Initially, regT1 still contains proto and regT2 still contains value. // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain. @@ -1941,16 +2006,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); Jump isInstance = branchPtr(Equal, regT2, regT1); - branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop); + emitJumpIfJSCell(regT2).linkTo(loop, this); // We get here either by dropping out of the loop, or if value was not an Object. Result is false. - valueIsImmediate.link(this); - valueIsNotObject.link(this); move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0); // isInstance jumps right down to here, to skip setting the result to false (it has already set true). isInstance.link(this); - emitPutVirtualRegister(currentInstruction[1].u.operand); + emitPutVirtualRegister(dst); } void JIT::emit_op_new_func(Instruction* currentInstruction) @@ -2127,9 +2190,9 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); @@ -2196,14 +2259,14 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) unsigned target = currentInstruction[2].u.operand; emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target); Jump isNonZero = emitJumpIfImmediateInteger(regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true))))); isNonZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jeq_null(Instruction* currentInstruction) { @@ -2215,16 +2278,16 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jneq_null(Instruction* currentInstruction) { @@ -2236,16 +2299,16 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) @@ -2255,9 +2318,9 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) unsigned target = currentInstruction[3].u.operand; emitGetVirtualRegister(src, regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target + 3); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target); - RECORD_JUMP_TARGET(target + 3); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jsr(Instruction* currentInstruction) @@ -2265,10 +2328,10 @@ void JIT::emit_op_jsr(Instruction* currentInstruction) int retAddrDst = currentInstruction[1].u.operand; int target = currentInstruction[2].u.operand; DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst)); - addJump(jump(), target + 2); + addJump(jump(), target); m_jsrSites.append(JSRInfo(storeLocation, label())); killLastResultRegister(); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_sret(Instruction* currentInstruction) @@ -2320,13 +2383,13 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_neq(Instruction* currentInstruction) @@ -2377,15 +2440,110 @@ void JIT::emit_op_throw(Instruction* currentInstruction) #endif } +void JIT::emit_op_get_pnames(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int breakTarget = currentInstruction[5].u.operand; + + JumpList isNotObject; + + emitGetVirtualRegister(base, regT0); + if (!m_codeBlock->isKnownNotImmediate(base)) + isNotObject.append(emitJumpIfNotJSCell(regT0)); + if (base != m_codeBlock->thisRegister()) { + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + } + + // We could inline the case where you have a valid cache, but + // this call doesn't seem to be hot. + Label isObject(this); + JITStubCall getPnamesStubCall(this, cti_op_get_pnames); + getPnamesStubCall.addArgument(regT0); + getPnamesStubCall.call(dst); + load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3); + store32(Imm32(0), addressFor(i)); + store32(regT3, addressFor(size)); + Jump end = jump(); + + isNotObject.link(this); + move(regT0, regT1); + and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT1); + addJump(branch32(Equal, regT1, Imm32(JSImmediate::FullTagTypeNull)), breakTarget); + + JITStubCall toObjectStubCall(this, cti_to_object); + toObjectStubCall.addArgument(regT0); + toObjectStubCall.call(base); + jump().linkTo(isObject, this); + + end.link(this); +} + void JIT::emit_op_next_pname(Instruction* currentInstruction) { - JITStubCall stubCall(this, cti_op_next_pname); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int it = currentInstruction[5].u.operand; + int target = currentInstruction[6].u.operand; + + JumpList callHasProperty; + + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); + + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2); + emitPutVirtualRegister(dst, regT2); + + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + emitGetVirtualRegister(base, regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); + + // Test base's prototype chain + loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3); + loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3); + addJump(branchTestPtr(Zero, Address(regT3)), target); + + Label checkPrototype(this); + loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); + callHasProperty.append(emitJumpIfNotJSCell(regT2)); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3))); + addPtr(Imm32(sizeof(Structure*)), regT3); + branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this); + + // Continue loop. + addJump(jump(), target); + + // Slow case: Ask the object if i is valid. + callHasProperty.link(this); + emitGetVirtualRegister(dst, regT1); + JITStubCall stubCall(this, cti_has_property); + stubCall.addArgument(regT0); + stubCall.addArgument(regT1); stubCall.call(); - Jump endOfIter = branchTestPtr(Zero, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); - addJump(jump(), currentInstruction[3].u.operand + 3); - endOfIter.link(this); + + // Test for valid key. + addJump(branchTest32(NonZero, regT0), target); + jump().linkTo(begin, this); + + // End of loop. + end.link(this); } void JIT::emit_op_push_scope(Instruction* currentInstruction) @@ -2469,8 +2627,8 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); - addJump(jump(), currentInstruction[2].u.operand + 2); - RECORD_JUMP_TARGET(currentInstruction[2].u.operand + 2); + addJump(jump(), currentInstruction[2].u.operand); + RECORD_JUMP_TARGET(currentInstruction[2].u.operand); } void JIT::emit_op_switch_imm(Instruction* currentInstruction) @@ -2696,32 +2854,20 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowC void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. - Label beginGetByValSlow(this); + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base array check + linkSlowCase(iter); // vector length check + linkSlowCase(iter); // empty value - notImm.link(this); JITStubCall stubCall(this, cti_op_get_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.call(currentInstruction[1].u.operand); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - // This is slow void JIT::emitSlow_that handles accesses to arrays above the fast cut-off. - // First, check if this is an access to the vector - linkSlowCase(iter); - branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), beginGetByValSlow); - - // okay, missed the fast region, but it is still in the vector. Get the value. - loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT2); - // Check whether the value loaded is zero; if so we need to return undefined. - branchTestPtr(Zero, regT2, beginGetByValSlow); - move(regT2, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand, regT0); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2735,14 +2881,14 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2750,7 +2896,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } } @@ -2764,7 +2910,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(regT0); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2772,36 +2918,26 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - // Normal slow cases - either is not an immediate imm, or is an array. - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; - notImm.link(this); { - JITStubCall stubCall(this, cti_op_put_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val)); - } + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base not array check + linkSlowCase(iter); // in vector check - // slow cases for immediate int accesses to arrays - linkSlowCase(iter); - linkSlowCase(iter); { - JITStubCall stubCall(this, cti_op_put_by_val_array); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - } + JITStubCall stubPutByValCall(this, cti_op_put_by_val); + stubPutByValCall.addArgument(regT0); + stubPutByValCall.addArgument(property, regT2); + stubPutByValCall.addArgument(value, regT2); + stubPutByValCall.call(); } void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2810,7 +2946,7 @@ void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowC JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2828,7 +2964,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted! + emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted! } void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2845,7 +2981,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2911,16 +3047,20 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + + linkSlowCaseIfNotJSCell(iter, value); + linkSlowCaseIfNotJSCell(iter, baseVal); + linkSlowCaseIfNotJSCell(iter, proto); linkSlowCase(iter); JITStubCall stubCall(this, cti_op_instanceof); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.addArgument(currentInstruction[4].u.operand, regT2); - stubCall.call(currentInstruction[1].u.operand); + stubCall.addArgument(value, regT2); + stubCall.addArgument(baseVal, regT2); + stubCall.addArgument(proto, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp index 08b3096..4241111 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -273,11 +273,14 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); + + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag))); + emitStore(dst, regT1, regT0); map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); } @@ -288,35 +291,16 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas unsigned base = currentInstruction[2].u.operand; unsigned property = currentInstruction[3].u.operand; - // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. - Label callGetByValJITStub(this); - linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base array check + linkSlowCase(iter); // vector length check + linkSlowCase(iter); // empty value JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(base); stubCall.addArgument(property); stubCall.call(dst); - - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - linkSlowCase(iter); // array fast cut-off check - - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), callGetByValJITStub); - - // Missed the fast region, but it is still in the vector. - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload - - // FIXME: Maybe we can optimize this comparison to JSValue(). - Jump skip = branch32(NotEqual, regT0, Imm32(0)); - branch32(Equal, regT1, Imm32(JSValue::CellTag), callGetByValJITStub); - - skip.link(this); - emitStore(dst, regT1, regT0); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) @@ -330,24 +314,27 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); - - 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)))); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - Jump skip = branch32(NotEqual, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::CellTag)); - addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), Imm32(0))); - skip.link(this); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); - inFastVector.link(this); + Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag)); + Label storeResult(this); emitLoad(value, regT1, regT0); store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); // payload store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4)); // tag + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + add32(Imm32(1), regT2, regT0); + store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -359,24 +346,13 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check + linkSlowCase(iter); // in vector check JITStubCall stubPutByValCall(this, cti_op_put_by_val); stubPutByValCall.addArgument(base); stubPutByValCall.addArgument(property); stubPutByValCall.addArgument(value); stubPutByValCall.call(); - - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - // Slow cases for immediate int accesses to arrays. - linkSlowCase(iter); // in vector check - linkSlowCase(iter); // written to slot check - - JITStubCall stubCall(this, cti_op_put_by_val_array); - stubCall.addArgument(regT1, regT0); - stubCall.addArgument(regT2); - stubCall.addArgument(value); - stubCall.call(); } void JIT::emit_op_get_by_id(Instruction* currentInstruction) @@ -545,22 +521,26 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res load32(Address(temp, offset + 4), resultTag); } +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure))); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack. JumpList failureCases; failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); - - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(oldStructure))); + failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); + testPrototype(oldStructure, failureCases); // Verify that nothing in the prototype chain has a setter for this property. - for (RefPtr<Structure>* it = chain->head(); *it; ++it) { - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(it->get()))); - } + for (RefPtr<Structure>* it = chain->head(); *it; ++it) + testPrototype(it->get(), failureCases); // Reallocate property storage if needed. Call callTarget; @@ -958,12 +938,16 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str void JIT::emit_op_get_by_val(Instruction* currentInstruction) { - emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1); + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); #if USE(JSVALUE64) // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. - // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if - // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation + // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if + // number was signed since m_vectorLength is always less than intmax (since the total allocation // size is always less than 4Gb). As such zero extending wil have been correct (and extending the value // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign // extending since it makes it easier to re-tag the value in the slow case. @@ -971,21 +955,25 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) #else emitFastArithImmToInt(regT1); #endif - emitJumpSlowCaseIfNotJSCell(regT0); + emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // Get the value from the vector loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); + addSlowCase(branchTestPtr(Zero, regT0)); + + emitPutVirtualRegister(dst); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) { - emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); #if USE(JSVALUE64) // See comment in op_get_by_val. @@ -993,23 +981,29 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) #else emitFastArithImmToInt(regT1); #endif - emitJumpSlowCaseIfNotJSCell(regT0); + emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - Jump inFastVector = branch32(Below, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); - // No; oh well, check if the access if within the vector - if so, we may still be okay. - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); + Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - // All good - put the value into the array. - inFastVector.link(this); - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); + Label storeResult(this); + emitGetVirtualRegister(value, regT0); storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + move(regT1, regT0); + add32(Imm32(1), regT0); + store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emit_op_put_by_index(Instruction* currentInstruction) @@ -1357,35 +1351,27 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res } } +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + move(ImmPtr(&asCell(structure->m_prototype)->m_structure), regT2); + move(ImmPtr(asCell(structure->m_prototype)->m_structure), regT3); + failureCases.append(branchPtr(NotEqual, Address(regT2), regT3)); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { JumpList failureCases; // Check eax is an object of the right Structure. failureCases.append(emitJumpIfNotJSCell(regT0)); failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); - JumpList successCases; - - // ecx = baseObject - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - // proto(ecx) = baseObject->structure()->prototype() - failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType))); + testPrototype(oldStructure, failureCases); - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - // ecx = baseObject->m_structure - for (RefPtr<Structure>* it = chain->head(); *it; ++it) { - // null check the prototype - successCases.append(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNull())))); - - // Check the structure id - failureCases.append(branchPtr(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(it->get()))); - - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType))); - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - } - - successCases.link(this); + for (RefPtr<Structure>* it = chain->head(); *it; ++it) + testPrototype(it->get(), failureCases); Call callTarget; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h index cb5354b..c5ed9e3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubCall.h @@ -26,7 +26,7 @@ #ifndef JITStubCall_h #define JITStubCall_h -#include <wtf/Platform.h> +#include "MacroAssemblerCodeRef.h" #if ENABLE(JIT) @@ -36,7 +36,7 @@ namespace JSC { public: JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Cell) , m_stackIndex(stackIndexStart) { @@ -44,7 +44,7 @@ namespace JSC { JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Cell) , m_stackIndex(stackIndexStart) { @@ -52,7 +52,7 @@ namespace JSC { JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(VoidPtr) , m_stackIndex(stackIndexStart) { @@ -60,7 +60,7 @@ namespace JSC { JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Int) , m_stackIndex(stackIndexStart) { @@ -68,7 +68,7 @@ namespace JSC { JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Int) , m_stackIndex(stackIndexStart) { @@ -76,7 +76,7 @@ namespace JSC { JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Void) , m_stackIndex(stackIndexStart) { @@ -85,7 +85,7 @@ namespace JSC { #if USE(JSVALUE32_64) JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) : m_jit(jit) - , m_stub(reinterpret_cast<void*>(stub)) + , m_stub(stub) , m_returnType(Value) , m_stackIndex(stackIndexStart) { @@ -171,7 +171,7 @@ namespace JSC { m_jit->restoreArgumentReference(); JIT::Call call = m_jit->call(); - m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub)); + m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub.value())); #if ENABLE(OPCODE_SAMPLING) if (m_jit->m_bytecodeIndex != (unsigned)-1) @@ -225,7 +225,7 @@ namespace JSC { static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference(). JIT* m_jit; - void* m_stub; + FunctionPtr m_stub; enum { Void, VoidPtr, Int, Value, Cell } m_returnType; size_t m_stackIndex; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp index 065b7ea..90ea807 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp @@ -75,6 +75,12 @@ namespace JSC { #define THUMB_FUNC_PARAM(name) #endif +#if PLATFORM(LINUX) && PLATFORM(X86_64) +#define SYMBOL_STRING_RELOCATION(name) #name "@plt" +#else +#define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name) +#endif + #if USE(JSVALUE32_64) #if COMPILER(GCC) && PLATFORM(X86) @@ -112,7 +118,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" #if !USE(JIT_STUB_ARGUMENT_VA_LIST) "movl %esp, %ecx" "\n" #endif - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addl $0x3c, %esp" "\n" "popl %ebx" "\n" "popl %edi" "\n" @@ -175,7 +181,7 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addq $0x48, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" @@ -239,7 +245,7 @@ asm volatile ( ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" - "bl " SYMBOL_STRING(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" @@ -365,7 +371,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" #if !USE(JIT_STUB_ARGUMENT_VA_LIST) "movl %esp, %ecx" "\n" #endif - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addl $0x1c, %esp" "\n" "popl %ebx" "\n" "popl %edi" "\n" @@ -434,7 +440,7 @@ asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING(cti_vm_throw) "\n" + "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "addq $0x78, %rsp" "\n" "popq %rbx" "\n" "popq %r15" "\n" @@ -498,7 +504,7 @@ asm volatile ( ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "cpy r0, sp" "\n" - "bl " SYMBOL_STRING(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" "ldr r6, [sp, #0x2c]" "\n" "ldr r5, [sp, #0x28]" "\n" "ldr r4, [sp, #0x24]" "\n" @@ -554,7 +560,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov lr, r6" "\n" "add r8, pc, #4" "\n" "str r8, [sp, #-4]!" "\n" - "b " SYMBOL_STRING(cti_vm_throw) "\n" + "b " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" // Both has the same return sequence ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" @@ -694,11 +700,15 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { - StructureChain* prototypeChain = structure->prototypeChain(callFrame); - if (!prototypeChain->isCacheable() || structure->isDictionary()) { + if (structure->isDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } + + // put_by_id_transition checks the prototype chain for setters. + normalizePrototypeChain(callFrame, baseCell); + + StructureChain* prototypeChain = structure->prototypeChain(callFrame); stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain); JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress); return; @@ -774,17 +784,13 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co return; } - size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); if (!count) { stubInfo->accessType = access_get_by_id_generic; return; } StructureChain* prototypeChain = structure->prototypeChain(callFrame); - if (!prototypeChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); - return; - } stubInfo->initGetByIdChain(structure, prototypeChain); JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress); } @@ -1326,15 +1332,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); - } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) { - StructureChain* protoChain = structure->prototypeChain(callFrame); - if (!protoChain->isCacheable()) { - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); - return JSValue::encode(result); - } - + } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase())) { int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + + StructureChain* protoChain = structure->prototypeChain(callFrame); JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) @@ -1412,7 +1414,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof) // ECMA-262 15.3.5.3: // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function). - TypeInfo typeInfo(UnspecifiedType, 0); + TypeInfo typeInfo(UnspecifiedType); if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) { CallFrame* callFrame = stackFrame.callFrame; CodeBlock* codeBlock = callFrame->codeBlock(); @@ -1942,28 +1944,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) CHECK_FOR_EXCEPTION_AT_END(); } -DEFINE_STUB_FUNCTION(void, op_put_by_val_array) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - JSValue baseValue = stackFrame.args[0].jsValue(); - int i = stackFrame.args[1].int32(); - JSValue value = stackFrame.args[2].jsValue(); - - ASSERT(isJSArray(stackFrame.globalData, baseValue)); - - if (LIKELY(i >= 0)) - asArray(baseValue)->JSArray::put(callFrame, i, value); - else { - Identifier property(callFrame, UString::from(i)); - PutPropertySlot slot; - baseValue.put(callFrame, property, value, slot); - } - - CHECK_FOR_EXCEPTION_AT_END(); -} - DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2672,7 +2652,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw) if (!handler) { *stackFrame.exception = exceptionValue; - STUB_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiOpThrowNotCaught)); + STUB_SET_RETURN_ADDRESS(FunctionPtr(ctiOpThrowNotCaught).value()); return JSValue::encode(jsNull()); } @@ -2687,18 +2667,22 @@ DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames) { STUB_INIT_STACK_FRAME(stackFrame); - return JSPropertyNameIterator::create(stackFrame.callFrame, stackFrame.args[0].jsValue()); + CallFrame* callFrame = stackFrame.callFrame; + JSObject* o = stackFrame.args[0].jsObject(); + Structure* structure = o->structure(); + JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); + if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) + jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); + return jsPropertyNameIterator; } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_next_pname) +DEFINE_STUB_FUNCTION(int, has_property) { STUB_INIT_STACK_FRAME(stackFrame); - JSPropertyNameIterator* it = stackFrame.args[0].propertyNameIterator(); - JSValue temp = it->next(stackFrame.callFrame); - if (!temp) - it->invalidate(); - return JSValue::encode(temp); + JSObject* base = stackFrame.args[0].jsObject(); + JSString* property = stackFrame.args[1].jsString(); + return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value())); } DEFINE_STUB_FUNCTION(JSObject*, op_push_scope) @@ -3039,6 +3023,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw) return JSValue::encode(exceptionValue); } +DEFINE_STUB_FUNCTION(EncodedJSValue, to_object) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + CallFrame* callFrame = stackFrame.callFrame; + return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame)); +} + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h index 46973ee..ccbcd2a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h @@ -63,6 +63,7 @@ namespace JSC { int32_t asInt32; JSValue jsValue() { return JSValue::decode(asEncodedJSValue); } + JSObject* jsObject() { return static_cast<JSObject*>(asPointer); } Identifier& identifier() { return *static_cast<Identifier*>(asPointer); } int32_t int32() { return asInt32; } CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); } @@ -285,7 +286,6 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION); @@ -307,6 +307,7 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION); @@ -332,6 +333,7 @@ extern "C" { int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION); int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION); int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION); + int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION); @@ -345,7 +347,6 @@ extern "C" { void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_val_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION); diff --git a/src/3rdparty/webkit/JavaScriptCore/jsc.cpp b/src/3rdparty/webkit/JavaScriptCore/jsc.cpp index 9399b1a..b6bc0aa 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jsc.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jsc.cpp @@ -29,6 +29,7 @@ #include "JSArray.h" #include "JSFunction.h" #include "JSLock.h" +#include "JSString.h" #include "PrototypeFunction.h" #include "SamplingTool.h" #include <math.h> diff --git a/src/3rdparty/webkit/JavaScriptCore/jsc.pro b/src/3rdparty/webkit/JavaScriptCore/jsc.pro deleted file mode 100644 index ba880ff..0000000 --- a/src/3rdparty/webkit/JavaScriptCore/jsc.pro +++ /dev/null @@ -1,31 +0,0 @@ -TEMPLATE = app -TARGET = jsc -DESTDIR = . -SOURCES = jsc.cpp -QT -= gui -CONFIG -= app_bundle -CONFIG += building-libs -win32-*: CONFIG += console -win32-msvc*: CONFIG += exceptions_off stl_off - -include($$PWD/../WebKit.pri) - -CONFIG += link_pkgconfig - -QMAKE_RPATHDIR += $$OUTPUT_DIR/lib - -isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/.. -CONFIG(debug, debug|release) { - OBJECTS_DIR = obj/debug -} else { # Release - OBJECTS_DIR = obj/release -} -OBJECTS_DIR_WTR = $$OBJECTS_DIR$${QMAKE_DIR_SEP} -include($$PWD/JavaScriptCore.pri) - -lessThan(QT_MINOR_VERSION, 4) { - DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE="" -} - -*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 -*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y index 85fd163..6d953df 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y @@ -27,6 +27,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Lexer.h" #include "NodeConstructors.h" #include "NodeInfo.h" #include <stdlib.h> @@ -48,7 +49,6 @@ #define YYERROR_VERBOSE #endif -int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp index 785b219..df30838 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp @@ -46,12 +46,6 @@ using namespace JSC; #include "Lookup.h" #include "Lexer.lut.h" -// A bridge for yacc from the C world to the C++ world. -int jscyylex(void* lvalp, void* llocp, void* globalData) -{ - return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); -} - namespace JSC { static const UChar byteOrderMark = 0xFEFF; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h index 174e05a..c76696c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h @@ -136,6 +136,12 @@ namespace JSC { return (convertHex(c1, c2) << 8) | convertHex(c3, c4); } + // A bridge for yacc from the C world to the C++ world. + inline int jscyylex(void* lvalp, void* llocp, void* globalData) + { + return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); + } + } // namespace JSC #endif // Lexer_h diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp index 3bd318a..b1e317e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp @@ -1468,14 +1468,16 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds if (!m_lexpr->isLocation()) return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference."); - RefPtr<Label> continueTarget = generator.newLabel(); - generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_init) generator.emitNode(generator.ignoredResult(), m_init); - RegisterID* forInBase = generator.emitNode(m_expr); - RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase); + + RefPtr<RegisterID> base = generator.newTemporary(); + generator.emitNode(base.get(), m_expr); + RefPtr<RegisterID> i = generator.newTemporary(); + RefPtr<RegisterID> size = generator.newTemporary(); + RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); generator.emitJump(scope->continueTarget()); RefPtr<Label> loopStart = generator.newLabel(); @@ -1517,7 +1519,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitNode(dst, m_statement); generator.emitLabel(scope->continueTarget()); - generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get()); + generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); generator.emitLabel(scope->breakTarget()); return dst; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h index 2fd4fc1..eef8e93 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h @@ -34,7 +34,7 @@ namespace JSC { class ParserArenaDeletable; class ParserArenaRefCounted; - class IdentifierArena { + class IdentifierArena : public FastAllocBase { public: ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length); const Identifier& makeNumericIdentifier(JSGlobalData*, double number); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h index 5be84a2..9b674a2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h @@ -85,9 +85,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + private: void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp index 0237fd4..fb44494 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -50,7 +50,7 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, NonNullPassRefPtr<Structure> putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum); } -static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) +static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) { // a single numeric argument denotes the array size (!) if (args.size() == 1 && args.at(0).isNumber()) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp index 86e3f1b..7a89447 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -149,10 +149,11 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.inherits(&JSArray::info)) + bool isRealArray = isJSArray(&exec->globalData(), thisValue); + if (!isRealArray && !thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); - JSObject* thisObj = asArray(thisValue); - + JSArray* thisObj = asArray(thisValue); + HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) { if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth) @@ -163,34 +164,48 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue if (alreadyVisited) return jsEmptyString(exec); // return an empty string, avoiding infinite recursion. - Vector<UChar, 256> strBuffer; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned totalSize = length ? length - 1 : 0; + Vector<RefPtr<UString::Rep>, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { - if (k >= 1) - strBuffer.append(','); - if (!strBuffer.data()) { - JSObject* error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - break; - } - - JSValue element = thisObj->get(exec, k); + JSValue element; + if (isRealArray && thisObj->canGetIndex(k)) + element = thisObj->getIndex(k); + else + element = thisObj->get(exec, k); + if (element.isUndefinedOrNull()) continue; - + UString str = element.toString(exec); - strBuffer.append(str.data(), str.size()); - + strBuffer[k] = str.rep(); + totalSize += str.size(); + if (!strBuffer.data()) { JSObject* error = Error::create(exec, GeneralError, "Out of memory"); exec->setException(error); } - + if (exec->hadException()) break; } arrayVisitedElements.remove(thisObj); - return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0)); + if (!totalSize) + return jsEmptyString(exec); + Vector<UChar> buffer; + buffer.reserveCapacity(totalSize); + if (!buffer.data()) + return throwError(exec, GeneralError, "Out of memory"); + + for (unsigned i = 0; i < length; i++) { + if (i) + buffer.append(','); + if (RefPtr<UString::Rep> rep = strBuffer[i]) + buffer.append(rep->data(), rep->size()); + } + ASSERT(buffer.size() == totalSize); + unsigned finalSize = buffer.size(); + return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false)); } JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h index 28f796a..69c2e51 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp index 01e36c4..f91f36f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp @@ -240,9 +240,7 @@ void Heap::destroy() template <HeapType heapType> 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 -#if PLATFORM(DARWIN) && !PLATFORM(QT) +#if PLATFORM(DARWIN) vm_address_t address = 0; // FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>. vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); @@ -334,9 +332,7 @@ NEVER_INLINE void Heap::freeBlock(size_t 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 -#if PLATFORM(DARWIN) && !PLATFORM(QT) +#if PLATFORM(DARWIN) vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE); #elif PLATFORM(SYMBIAN) userChunk->Free(reinterpret_cast<TAny*>(block)); @@ -1043,16 +1039,6 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack) #endif } -void Heap::setGCProtectNeedsLocking() -{ - // Most clients do not need to call this, with the notable exception of WebCore. - // Clients that use shared heap have JSLock protection, while others are supposed - // to do explicit locking. WebCore violates this contract in Database code, - // which calls gcUnprotect from a secondary thread. - if (!m_protectedValuesMutex) - m_protectedValuesMutex.set(new Mutex); -} - void Heap::protect(JSValue k) { ASSERT(k); @@ -1061,13 +1047,7 @@ void Heap::protect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.add(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::unprotect(JSValue k) @@ -1078,28 +1058,16 @@ void Heap::unprotect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.remove(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::markProtectedObjects(MarkStack& markStack) { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) { markStack.append(it->first); markStack.drain(); } - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } template <HeapType heapType> size_t Heap::sweep() @@ -1291,9 +1259,6 @@ size_t Heap::globalObjectCount() size_t Heap::protectedGlobalObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - size_t count = 0; if (JSGlobalObject* head = m_globalData->head) { JSGlobalObject* o = head; @@ -1304,23 +1269,12 @@ size_t Heap::protectedGlobalObjectCount() } while (o != head); } - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return count; } size_t Heap::protectedObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - - size_t result = m_protectedValues.size(); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - - return result; + return m_protectedValues.size(); } static const char* typeName(JSCell* cell) @@ -1342,16 +1296,10 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts() { HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) counts->add(typeName(it->first)); - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return counts; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h index 0ecff19..9ca9d18 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h @@ -71,14 +71,6 @@ namespace JSC { void destroy(); -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - // We can inline these functions because everything is compiled as - // one file, so the heapAllocate template definitions are available. - // However, allocateNumber is used via jsNumberCell outside JavaScriptCore. - // Thus allocateNumber needs to provide a non-inline version too. - void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); } - void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); } -#endif void* allocateNumber(size_t); void* allocate(size_t); @@ -96,7 +88,6 @@ namespace JSC { }; Statistics statistics() const; - void setGCProtectNeedsLocking(); void protect(JSValue); void unprotect(JSValue); @@ -151,7 +142,6 @@ namespace JSC { CollectorHeap primaryHeap; CollectorHeap numberHeap; - OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking(). ProtectCountSet m_protectedValues; HashSet<MarkedArgumentBuffer*>* m_markListSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp index 6b479ae..4cd58f5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp @@ -22,6 +22,8 @@ #include "config.h" #include "DateInstance.h" +#include "JSGlobalObject.h" + #include <math.h> #include <wtf/DateMath.h> #include <wtf/MathExtras.h> @@ -45,6 +47,13 @@ DateInstance::DateInstance(NonNullPassRefPtr<Structure> structure) { } +DateInstance::DateInstance(ExecState* exec, double time) + : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) + , m_cache(0) +{ + setInternalValue(jsNumber(exec, timeClip(time))); +} + DateInstance::~DateInstance() { delete m_cache; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h index c8edc2f..36d90b1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h @@ -31,6 +31,7 @@ namespace JSC { class DateInstance : public JSWrapperObject { public: + DateInstance(ExecState*, double); explicit DateInstance(NonNullPassRefPtr<Structure>); virtual ~DateInstance(); @@ -41,7 +42,7 @@ namespace JSC { bool getTime(double& milliseconds, int& offset) const; bool getUTCTime(double& milliseconds) const; - static const ClassInfo info; + static JS_EXPORTDATA const ClassInfo info; void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h index caed2d4..5fe4f47 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h @@ -39,8 +39,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | DateInstance::StructureFlags; + }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp index cc18b95..5bead90 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -66,6 +66,11 @@ JSValue createStackOverflowError(ExecState* exec) return createError(exec, RangeError, "Maximum call stack size exceeded."); } +JSValue createTypeError(ExecState* exec, const char* message) +{ + return createError(exec, TypeError, message); +} + JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h index 4c5bec1..e739d09 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h @@ -44,6 +44,7 @@ namespace JSC { JSValue createInterruptedExecutionException(JSGlobalData*); JSValue createStackOverflowError(ExecState*); + JSValue createTypeError(ExecState*, const char* message); JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*); JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull); JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h index 0e38549..d1d6a1d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h index 73dd854..68e9ea3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h @@ -50,7 +50,7 @@ namespace JSC { void setSetter(JSObject* setter) { m_setter = setter; } static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(GetterSetterType)); + return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren)); } private: virtual bool isGetterSetter() const; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h index b62ad3e..389b1c3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h @@ -37,9 +37,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | PrototypeFunction::StructureFlags; + private: virtual void markChildren(MarkStack&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h index fdd5cc1..de9a1d6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h @@ -42,10 +42,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; + InternalFunction(NonNullPassRefPtr<Structure> structure) : JSObject(structure) { } InternalFunction(JSGlobalData*, NonNullPassRefPtr<Structure>, const Identifier&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h index 88a8493..aca550e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h index 583b988..ee98191 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h @@ -66,7 +66,10 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: struct JSActivationData : public JSVariableObjectData { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp index c471dac..fd9e7b2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -136,9 +136,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure) unsigned initialCapacity = 0; m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_vectorLength = initialCapacity; - - m_fastAccessCutoff = 0; + m_vectorLength = initialCapacity; checkConsistency(); } @@ -150,7 +148,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialLength; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = 0; m_storage->m_sparseValueMap = 0; m_storage->lazyCreationData = 0; @@ -159,8 +157,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) for (size_t i = 0; i < initialCapacity; ++i) vector[i] = JSValue(); - m_fastAccessCutoff = 0; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); @@ -173,7 +169,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialCapacity; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = initialCapacity; m_storage->m_sparseValueMap = 0; @@ -182,8 +178,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) m_storage->m_vector[i] = *it; - m_fastAccessCutoff = initialCapacity; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); @@ -207,7 +201,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot return false; } - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (valueSlot) { slot.setValueSlot(&valueSlot); @@ -253,8 +247,8 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper if (isArrayIndex) { if (i >= m_storage->m_length) return false; - if (i < m_storage->m_vectorLength) { - JSValue value = m_storage->m_vector[i]; + if (i < m_vectorLength) { + JSValue& value = m_storage->m_vector[i]; if (value) { descriptor.setDescriptor(value, 0); return true; @@ -305,7 +299,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) m_storage->m_length = length; } - if (i < m_storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[i]; if (valueSlot) { valueSlot = value; @@ -313,8 +307,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) return; } valueSlot = value; - if (++m_storage->m_numValuesInVector == m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; checkConsistency(); return; } @@ -352,8 +345,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu if (increaseVectorLength(i + 1)) { storage = m_storage; storage->m_vector[i] = value; - if (++storage->m_numValuesInVector == storage->m_length) - m_fastAccessCutoff = storage->m_length; + ++storage->m_numValuesInVector; checkConsistency(); } else throwOutOfMemoryError(exec); @@ -363,7 +355,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Decide how many values it would be best to move from the map. unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; unsigned newVectorLength = increasedVectorLength(i + 1); - for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) + for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) newNumValuesInVector += map->contains(j); if (i >= MIN_SPARSE_ARRAY_INDEX) newNumValuesInVector -= map->contains(i); @@ -386,7 +378,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu return; } - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); @@ -404,7 +396,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu storage->m_vector[i] = value; - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; storage->m_numValuesInVector = newNumValuesInVector; m_storage = storage; @@ -431,7 +423,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) ArrayStorage* storage = m_storage; - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (!valueSlot) { checkConsistency(); @@ -439,8 +431,6 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) } valueSlot = JSValue(); --storage->m_numValuesInVector; - if (m_fastAccessCutoff > i) - m_fastAccessCutoff = i; checkConsistency(); return true; } @@ -472,7 +462,7 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); for (unsigned i = 0; i < usedVectorLength; ++i) { if (storage->m_vector[i]) propertyNames.add(Identifier::from(exec, i)); @@ -494,7 +484,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) ArrayStorage* storage = m_storage; - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; ASSERT(newLength > vectorLength); ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); unsigned newVectorLength = increasedVectorLength(newLength); @@ -503,7 +493,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) return false; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; for (unsigned i = vectorLength; i < newVectorLength; ++i) storage->m_vector[i] = JSValue(); @@ -521,10 +511,7 @@ void JSArray::setLength(unsigned newLength) unsigned length = m_storage->m_length; if (newLength < length) { - if (m_fastAccessCutoff > newLength) - m_fastAccessCutoff = newLength; - - unsigned usedVectorLength = min(length, storage->m_vectorLength); + unsigned usedVectorLength = min(length, m_vectorLength); for (unsigned i = newLength; i < usedVectorLength; ++i) { JSValue& valueSlot = storage->m_vector[i]; bool hadValue = valueSlot; @@ -563,20 +550,13 @@ JSValue JSArray::pop() JSValue result; - if (m_fastAccessCutoff > length) { - JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - ASSERT(result); - valueSlot = JSValue(); - --m_storage->m_numValuesInVector; - m_fastAccessCutoff = length; - } else if (length < m_storage->m_vectorLength) { + if (length < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - valueSlot = JSValue(); - if (result) + if (valueSlot) { --m_storage->m_numValuesInVector; - else + result = valueSlot; + valueSlot = JSValue(); + } else result = jsUndefined(); } else { result = jsUndefined(); @@ -604,11 +584,10 @@ void JSArray::push(ExecState* exec, JSValue value) { checkConsistency(); - if (m_storage->m_length < m_storage->m_vectorLength) { - ASSERT(!m_storage->m_vector[m_storage->m_length]); + if (m_storage->m_length < m_vectorLength) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -618,8 +597,8 @@ void JSArray::push(ExecState* exec, JSValue value) if (!map || map->isEmpty()) { if (increaseVectorLength(m_storage->m_length + 1)) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -837,7 +816,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (!m_storage->m_length) return; - unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items tree.abstractor().m_exec = exec; @@ -886,7 +865,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) { throwOutOfMemoryError(exec); @@ -926,7 +905,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) m_storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; m_storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -934,10 +912,16 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - args.append(getIndex(i)); + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + args.append(v); + } + for (; i < m_storage->m_length; ++i) args.append(get(exec, i)); } @@ -946,12 +930,17 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz { ASSERT(m_storage->m_length == maxSize); UNUSED_PARAM(maxSize); - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - buffer[i] = getIndex(i); - uint32_t size = m_storage->m_length; - for (; i < size; ++i) + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + buffer[i] = v; + } + + for (; i < m_storage->m_length; ++i) buffer[i] = get(exec, i); } @@ -961,7 +950,7 @@ unsigned JSArray::compactForSorting() ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); unsigned numDefined = 0; unsigned numUndefined = 0; @@ -985,7 +974,7 @@ unsigned JSArray::compactForSorting() if (SparseArrayValueMap* map = storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries - if not, // exception is thrown by caller. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) @@ -1006,7 +995,6 @@ unsigned JSArray::compactForSorting() for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -1032,30 +1020,27 @@ void JSArray::checkConsistency(ConsistencyCheckType type) if (type == SortConsistencyCheck) ASSERT(!m_storage->m_sparseValueMap); - ASSERT(m_fastAccessCutoff <= m_storage->m_length); - ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector); - unsigned numValuesInVector = 0; - for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) { + for (unsigned i = 0; i < m_vectorLength; ++i) { if (JSValue value = m_storage->m_vector[i]) { ASSERT(i < m_storage->m_length); if (type != DestructorConsistencyCheck) value->type(); // Likely to crash if the object was deallocated. ++numValuesInVector; } else { - ASSERT(i >= m_fastAccessCutoff); if (type == SortConsistencyCheck) ASSERT(i >= m_storage->m_numValuesInVector); } } ASSERT(numValuesInVector == m_storage->m_numValuesInVector); + ASSERT(numValuesInVector <= m_storage->m_length); if (m_storage->m_sparseValueMap) { SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end(); for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) { unsigned index = it->first; ASSERT(index < m_storage->m_length); - ASSERT(index >= m_storage->m_vectorLength); + ASSERT(index >= m_vectorLength); ASSERT(index <= MAX_ARRAY_INDEX); ASSERT(it->second); if (type != DestructorConsistencyCheck) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h index 12768a4..8c22451 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h @@ -29,7 +29,6 @@ namespace JSC { struct ArrayStorage { unsigned m_length; - unsigned m_vectorLength; unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily. @@ -63,18 +62,24 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(); - bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; } + bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } JSValue getIndex(unsigned i) { ASSERT(canGetIndex(i)); return m_storage->m_vector[i]; } - bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; } - JSValue setIndex(unsigned i, JSValue v) + bool canSetIndex(unsigned i) { return i < m_vectorLength; } + void setIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); - return m_storage->m_vector[i] = v; + JSValue& x = m_storage->m_vector[i]; + if (!x) { + ++m_storage->m_numValuesInVector; + if (i >= m_storage->m_length) + m_storage->m_length = i + 1; + } + x = v; } void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -82,12 +87,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } inline void markChildrenDirect(MarkStack& markStack); protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); @@ -110,7 +116,7 @@ namespace JSC { enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - unsigned m_fastAccessCutoff; + unsigned m_vectorLength; ArrayStorage* m_storage; }; @@ -139,7 +145,7 @@ namespace JSC { ArrayStorage* storage = m_storage; - unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); if (SparseArrayValueMap* map = storage->m_sparseValueMap) { @@ -152,7 +158,7 @@ namespace JSC { inline void MarkStack::markChildren(JSCell* cell) { ASSERT(Heap::isCellMarked(cell)); - if (cell->structure()->typeInfo().hasDefaultMark()) { + if (!cell->structure()->typeInfo().overridesMarkChildren()) { #ifdef NDEBUG asObject(cell)->markChildrenDirect(*this); #else diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp index 90d39f0..5e5003b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp @@ -45,7 +45,7 @@ JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) { - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark)); + PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); return result; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h index 006f4a2..fe6e124 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h @@ -91,6 +91,9 @@ namespace JSC { WTF::ByteArray* storage() const { return m_storage.get(); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; + private: enum VPtrStealingHackType { VPtrStealingHack }; JSByteArray(VPtrStealingHackType) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp index aa93252..fae056e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp @@ -78,11 +78,7 @@ extern const double Inf = NaNInf.doubles.Inf_Double; void* JSCell::operator new(size_t size, ExecState* exec) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocate(size); -#else return exec->heap()->allocate(size); -#endif } bool JSCell::getUInt32(uint32_t&) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h index 503c6c4..16a5131 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h @@ -112,14 +112,6 @@ namespace JSC { Structure* m_structure; }; - // FIXME: We should deprecate this and just use JSValue::asCell() instead. - JSCell* asCell(JSValue); - - inline JSCell* asCell(JSValue value) - { - return value.asCell(); - } - inline JSCell::JSCell(Structure* structure) : m_structure(structure) { @@ -162,11 +154,7 @@ namespace JSC { inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } // --- JSValue inlines ---------------------------- @@ -342,11 +330,6 @@ namespace JSC { append(value.asCell()); } - inline void Structure::markAggregate(MarkStack& markStack) - { - markStack.append(m_prototype); - } - inline Heap* Heap::heap(JSValue v) { if (!v.isCell()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h index a9ac63e..b4356c4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h @@ -61,7 +61,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } NativeFunction nativeFunction() @@ -72,6 +72,9 @@ namespace JSC { virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); + protected: + const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags; + private: JSFunction(NonNullPassRefPtr<Structure>); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp index 3bb281e..cf3f1d1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -89,7 +89,7 @@ static inline void markIfNeeded(MarkStack& markStack, JSValue v) static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) { if (s) - s->markAggregate(markStack); + markIfNeeded(markStack, s->storedPrototype()); } JSGlobalObject::~JSGlobalObject() @@ -394,6 +394,21 @@ void JSGlobalObject::markChildren(MarkStack& markStack) markIfNeeded(markStack, d()->methodCallDummy); markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->argumentsStructure); + markIfNeeded(markStack, d()->arrayStructure); + markIfNeeded(markStack, d()->booleanObjectStructure); + markIfNeeded(markStack, d()->callbackConstructorStructure); + markIfNeeded(markStack, d()->callbackFunctionStructure); + markIfNeeded(markStack, d()->callbackObjectStructure); + markIfNeeded(markStack, d()->dateStructure); + markIfNeeded(markStack, d()->emptyObjectStructure); + markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->functionStructure); + markIfNeeded(markStack, d()->numberObjectStructure); + markIfNeeded(markStack, d()->prototypeFunctionStructure); + markIfNeeded(markStack, d()->regExpMatchesArrayStructure); + markIfNeeded(markStack, d()->regExpStructure); + markIfNeeded(markStack, d()->stringObjectStructure); // No need to mark the other structures, because their prototypes are all // guaranteed to be referenced elsewhere. @@ -448,11 +463,7 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h index 2106783..720d3a5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h @@ -267,10 +267,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; + struct GlobalPropertyInfo { GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) : identifier(i) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h index 0d9aca6..a271c4e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h @@ -62,10 +62,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + // JSValue methods virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h index 6a48081..309488f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h @@ -68,23 +68,15 @@ namespace JSC { void* operator new(size_t size, ExecState* exec) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocateNumber(size); - #else return exec->heap()->allocateNumber(size); - #endif } void* operator new(size_t size, JSGlobalData* globalData) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocateNumber(size); - #else return globalData->heap.allocateNumber(size); - #endif } - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: JSNumberCell(JSGlobalData* globalData, double value) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h index 65c9803..ec3fa40 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h @@ -41,11 +41,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } static void markStringifiers(MarkStack&, Stringifier*); + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp index db2a9b2..6932ded 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp @@ -42,6 +42,25 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSObject); +static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) +{ + // Add properties from the static hashtables of properties + for (; classInfo; classInfo = classInfo->parentClass) { + const HashTable* table = classInfo->propHashTable(exec); + if (!table) + continue; + table->initializeIfNeeded(exec); + ASSERT(table->table); + + int hashSizeMask = table->compactSize - 1; + const HashEntry* entry = table->table; + for (int i = 0; i <= hashSizeMask; ++i, ++entry) { + if (entry->key() && !(entry->attributes() & DontEnum)) + propertyNames.add(entry->key()); + } + } +} + void JSObject::markChildren(MarkStack& markStack) { #ifndef NDEBUG @@ -424,12 +443,29 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getEnumerablePropertyNames(exec, propertyNames, this); + getOwnPropertyNames(exec, propertyNames); + + if (prototype().isNull()) + return; + + JSObject* prototype = asObject(this->prototype()); + while(1) { + if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { + prototype->getPropertyNames(exec, propertyNames); + break; + } + prototype->getOwnPropertyNames(exec, propertyNames); + JSValue nextProto = prototype->prototype(); + if (nextProto.isNull()) + break; + prototype = asObject(nextProto); + } } void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getOwnEnumerablePropertyNames(exec, propertyNames, this); + m_structure->getEnumerablePropertyNames(propertyNames); + getEnumerablePropertyNames(exec, classInfo(), propertyNames); } bool JSObject::toBoolean(ExecState*) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h index 84b5f4b..1dbab94 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h @@ -207,10 +207,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = 0; + void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { @@ -368,7 +370,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - if (structure()->typeInfo().hasStandardGetOwnPropertySlot()) + if (!structure()->typeInfo().overridesGetOwnPropertySlot()) return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot); return getOwnPropertySlot(exec, propertyName, slot); } @@ -682,7 +684,7 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) { JSCell::markChildren(markStack); - m_structure->markAggregate(markStack); + markStack.append(prototype()); PropertyStorage storage = propertyStorage(); size_t storageSize = m_structure->propertyStorageSize(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index e08a3d9..2cd9f75 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -29,26 +29,56 @@ #include "config.h" #include "JSPropertyNameIterator.h" +#include "JSGlobalObject.h" + namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); -JSPropertyNameIterator::~JSPropertyNameIterator() +JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { + ASSERT(!o->structure()->enumerationCache() || + o->structure()->enumerationCache()->cachedStructure() != o->structure() || + o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); + + PropertyNameArray propertyNames(exec); + o->getPropertyNames(exec, propertyNames); + JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data()); + + if (o->structure()->isDictionary()) + return jsPropertyNameIterator; + + if (o->structure()->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + + size_t count = normalizePrototypeChain(exec, o); + StructureChain* structureChain = o->structure()->prototypeChain(exec); + RefPtr<Structure>* structure = structureChain->head(); + for (size_t i = 0; i < count; ++i) { + if (structure[i]->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + } + + jsPropertyNameIterator->setCachedPrototypeChain(structureChain); + jsPropertyNameIterator->setCachedStructure(o->structure()); + o->structure()->setEnumerationCache(jsPropertyNameIterator); + return jsPropertyNameIterator; } -void JSPropertyNameIterator::markChildren(MarkStack& markStack) +JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i) { - JSCell::markChildren(markStack); - if (m_object) - markStack.append(m_object); + JSValue& identifier = m_jsStrings[i]; + if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec)) + return identifier; + + if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value()))) + return JSValue(); + return identifier; } -void JSPropertyNameIterator::invalidate() +void JSPropertyNameIterator::markChildren(MarkStack& markStack) { - ASSERT(m_position == m_end); - m_object = 0; - m_data.clear(); + markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h index d2849a8..0559e0b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -31,6 +31,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Operations.h" #include "PropertyNameArray.h" namespace JSC { @@ -39,73 +40,51 @@ namespace JSC { class JSObject; class JSPropertyNameIterator : public JSCell { - public: - static JSPropertyNameIterator* create(ExecState*, JSValue); - - virtual ~JSPropertyNameIterator(); - - virtual void markChildren(MarkStack&); + friend class JIT; - JSValue next(ExecState*); - void invalidate(); + public: + static JSPropertyNameIterator* create(ExecState*, JSObject*); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren)); } + + virtual void markChildren(MarkStack&); + + JSValue get(ExecState*, JSObject*, size_t i); + size_t size() { return m_jsStringsSize; } + + void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } + Structure* cachedStructure() { return m_cachedStructure; } + + void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } + StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } + private: - JSPropertyNameIterator(ExecState*); - JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); + JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData); - JSObject* m_object; - RefPtr<PropertyNameArrayData> m_data; - PropertyNameArrayData::const_iterator m_position; - PropertyNameArrayData::const_iterator m_end; + Structure* m_cachedStructure; + RefPtr<StructureChain> m_cachedPrototypeChain; + size_t m_jsStringsSize; + OwnArrayPtr<JSValue> m_jsStrings; }; -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec) +inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData) : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(0) - , m_position(0) - , m_end(0) + , m_cachedStructure(0) + , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) + , m_jsStrings(new JSValue[m_jsStringsSize]) { + PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); + for (size_t i = 0; i < m_jsStringsSize; ++i) + m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring()); } -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData) - : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(object) - , m_data(propertyNameArrayData) - , m_position(m_data->begin()) - , m_end(m_data->end()) -{ -} - -inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v) +inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache) { - if (v.isUndefinedOrNull()) - return new (exec) JSPropertyNameIterator(exec); - - JSObject* o = v.toObject(exec); - PropertyNameArray propertyNames(exec); - o->getPropertyNames(exec, propertyNames); - return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData()); -} - -inline JSValue JSPropertyNameIterator::next(ExecState* exec) -{ - if (m_position == m_end) - return JSValue(); - - if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec)) - return jsOwnedString(exec, (*m_position++).ustring()); - - do { - if (m_object->hasProperty(exec, *m_position)) - return jsOwnedString(exec, (*m_position++).ustring()); - m_position++; - } while (m_position != m_end); - - return JSValue(); + ASSERT(!isDictionary()); + m_enumerationCache = enumerationCache; } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h index 5eb0e4b..2542878 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -57,7 +57,10 @@ namespace JSC{ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp index 91ddaeb..20ba868 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp @@ -139,45 +139,4 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); } -JSString* jsString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s); -} - -JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) -{ - ASSERT(offset <= static_cast<unsigned>(s.size())); - ASSERT(length <= static_cast<unsigned>(s.size())); - ASSERT(offset + length <= static_cast<unsigned>(s.size())); - if (!length) - return globalData->smallStrings.emptyString(globalData); - if (length == 1) { - UChar c = s.data()[offset]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); -} - -JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h index 1e46551..39dfe75 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h @@ -92,7 +92,7 @@ namespace JSC { bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); } JSString* getIndex(JSGlobalData*, unsigned); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: enum VPtrStealingHackType { VPtrStealingHack }; @@ -169,6 +169,47 @@ namespace JSC { return jsSingleCharacterSubstring(globalData, m_value, i); } + inline JSString* jsString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s); + } + + inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) + { + ASSERT(offset <= static_cast<unsigned>(s.size())); + ASSERT(length <= static_cast<unsigned>(s.size())); + ASSERT(offset + length <= static_cast<unsigned>(s.size())); + if (!length) + return globalData->smallStrings.emptyString(globalData); + if (length == 1) { + UChar c = s.data()[offset]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); + } + + inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); + } + inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h index 279510b..7c89600 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h @@ -40,9 +40,9 @@ namespace JSC { static const unsigned OverridesHasInstance = 1 << 2; static const unsigned ImplementsDefaultHasInstance = 1 << 3; static const unsigned NeedsThisConversion = 1 << 4; - static const unsigned HasStandardGetOwnPropertySlot = 1 << 5; - static const unsigned HasDefaultMark = 1 << 6; - static const unsigned HasDefaultGetPropertyNames = 1 << 7; + static const unsigned OverridesGetOwnPropertySlot = 1 << 5; + static const unsigned OverridesMarkChildren = 1 << 6; + static const unsigned OverridesGetPropertyNames = 1 << 7; class TypeInfo { friend class JIT; @@ -63,9 +63,9 @@ namespace JSC { bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; } bool overridesHasInstance() const { return m_flags & OverridesHasInstance; } bool needsThisConversion() const { return m_flags & NeedsThisConversion; } - bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; } - bool hasDefaultMark() const { return m_flags & HasDefaultMark; } - bool hasDefaultGetPropertyNames() const { return m_flags & HasDefaultGetPropertyNames; } + bool overridesGetOwnPropertySlot() const { return m_flags & OverridesGetOwnPropertySlot; } + bool overridesMarkChildren() const { return m_flags & OverridesMarkChildren; } + bool overridesGetPropertyNames() const { return m_flags & OverridesGetPropertyNames; } unsigned flags() const { return m_flags; } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 39a4093..699c1cd 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -110,7 +110,10 @@ char* JSValue::description() { static const size_t size = 32; static char description[size]; - if (isInt32()) + + if (!*this) + snprintf(description, size, "<JSValue()>"); + else if (isInt32()) snprintf(description, size, "Int32: %d", asInt32()); else if (isDouble()) snprintf(description, size, "Double: %lf", asDouble()); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h index 58e74b1..1063cdc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h @@ -213,7 +213,8 @@ namespace JSC { enum { FalseTag = 0xfffffffc }; enum { NullTag = 0xfffffffb }; enum { UndefinedTag = 0xfffffffa }; - enum { DeletedValueTag = 0xfffffff9 }; + enum { EmptyValueTag = 0xfffffff9 }; + enum { DeletedValueTag = 0xfffffff8 }; enum { LowestTag = DeletedValueTag }; @@ -372,6 +373,14 @@ namespace JSC { return static_cast<uint32_t>(val); } + // FIXME: We should deprecate this and just use JSValue::asCell() instead. + JSCell* asCell(JSValue); + + inline JSCell* asCell(JSValue value) + { + return value.asCell(); + } + ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const { if (isInt32()) @@ -427,7 +436,7 @@ namespace JSC { inline JSValue::JSValue() { - u.asBits.tag = CellTag; + u.asBits.tag = EmptyValueTag; u.asBits.payload = 0; } @@ -463,19 +472,26 @@ namespace JSC { inline JSValue::JSValue(JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(ptr); } inline JSValue::JSValue(const JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr)); } inline JSValue::operator bool() const { - return u.asBits.payload || tag() != CellTag; + ASSERT(tag() != DeletedValueTag); + return tag() != EmptyValueTag; } inline bool JSValue::operator==(const JSValue& other) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h index 66e78c3..d8b1479 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h @@ -60,10 +60,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags; // Subclasses of JSVariableObject can subclass this struct to add data // without increasing their own size (since there's a hard limit on the // size of a JSCell). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h index 723b75d..191ff3b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h @@ -38,7 +38,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h index ba00057e0..ea09f54 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h @@ -47,7 +47,7 @@ namespace JSC { } ALWAYS_INLINE void append(JSValue); - ALWAYS_INLINE void append(JSCell*); + void append(JSCell*); ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h index fee5ec5..7f474b8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h @@ -37,8 +37,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h index 908c55f..cf19b6f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h @@ -39,11 +39,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h index ca3923d..8223a90 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h @@ -30,17 +30,19 @@ namespace JSC { explicit NumberObject(NonNullPassRefPtr<Structure>); static const ClassInfo info; -#if USE(JSVALUE32) + static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: +#if USE(JSVALUE32) + static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; #else - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); - } + static const unsigned StructureFlags = JSWrapperObject::StructureFlags; #endif + private: virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp index a456423..837d5a6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -125,6 +125,7 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, return description; } +// FIXME: Use the enumeration cache. JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args) { if (!args.at(0).isObject()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h index 5da9e38..1aa68b3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h @@ -224,15 +224,15 @@ namespace JSC { return jsAddSlowCase(callFrame, v1, v2); } - inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot) + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase) { - JSCell* cell = asCell(baseValue); + JSCell* cell = asCell(base); size_t count = 0; - while (slot.slotBase() != cell) { + while (slotBase != cell) { JSValue v = cell->structure()->prototypeForLookup(callFrame); - // If we didn't find slotBase in baseValue's prototype chain, then baseValue + // If we didn't find slotBase in base's prototype chain, then base // must be a proxy for another object. if (v.isNull()) @@ -252,6 +252,25 @@ namespace JSC { return count; } + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base) + { + size_t count = 0; + while (1) { + JSValue v = base->structure()->prototypeForLookup(callFrame); + if (v.isNull()) + return count; + + base = asCell(v); + + // Since we're accessing a prototype in a loop, it's a good bet that it + // should not be treated as a dictionary. + if (base->structure()->isDictionary()) + asObject(base)->setStructure(Structure::fromDictionaryTransition(base->structure())); + + ++count; + } + } + ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain) { ScopeChainIterator iter = scopeChain->begin(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp index 0878e73..c28b6a4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -21,6 +21,9 @@ #include "config.h" #include "PropertyNameArray.h" +#include "Structure.h" +#include "StructureChain.h" + namespace JSC { static const size_t setThreshold = 20; @@ -44,7 +47,7 @@ void PropertyNameArray::add(UString::Rep* identifier) return; } - m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); + addKnownUnique(identifier); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h index afcc83f..3dbcc9d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h @@ -23,45 +23,35 @@ #include "CallFrame.h" #include "Identifier.h" -#include "Structure.h" #include <wtf/HashSet.h> +#include <wtf/OwnArrayPtr.h> #include <wtf/Vector.h> namespace JSC { + + class Structure; + class StructureChain; + // FIXME: Rename to PropertyNameArray. class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> { public: typedef Vector<Identifier, 20> PropertyNameVector; - typedef PropertyNameVector::const_iterator const_iterator; static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); } - const_iterator begin() const { return m_propertyNameVector.begin(); } - const_iterator end() const { return m_propertyNameVector.end(); } - PropertyNameVector& propertyNameVector() { return m_propertyNameVector; } - void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } - Structure* cachedStructure() const { return m_cachedStructure; } - - void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } - StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } - private: PropertyNameArrayData() - : m_cachedStructure(0) { } PropertyNameVector m_propertyNameVector; - Structure* m_cachedStructure; - RefPtr<StructureChain> m_cachedPrototypeChain; }; + // FIXME: Rename to PropertyNameArrayBuilder. class PropertyNameArray { public: - typedef PropertyNameArrayData::const_iterator const_iterator; - PropertyNameArray(JSGlobalData* globalData) : m_data(PropertyNameArrayData::create()) , m_globalData(globalData) @@ -82,21 +72,18 @@ namespace JSC { void add(UString::Rep*); void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } - size_t size() const { return m_data->propertyNameVector().size(); } - Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; } - const_iterator begin() const { return m_data->begin(); } - const_iterator end() const { return m_data->end(); } - void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; } PropertyNameArrayData* data() { return m_data.get(); } - PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } - void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; } - bool shouldCache() const { return m_shouldCache; } + // FIXME: Remove these functions. + typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator; + size_t size() const { return m_data->propertyNameVector().size(); } + const_iterator begin() const { return m_data->propertyNameVector().begin(); } + const_iterator end() const { return m_data->propertyNameVector().end(); } private: typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h index 224164d..a0d5443 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h @@ -22,8 +22,8 @@ #ifndef Protect_h #define Protect_h -#include "JSCell.h" #include "Collector.h" +#include "JSValue.h" namespace JSC { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp index dbf2d44..c609e08 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -90,28 +90,6 @@ const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, @end */ -struct RegExpConstructorPrivate : FastAllocBase { - // Global search cache / settings - RegExpConstructorPrivate() - : lastNumSubPatterns(0) - , multiline(false) - , lastOvectorIndex(0) - { - } - - const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } - Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } - Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } - void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } - - UString input; - UString lastInput; - Vector<int, 32> ovector[2]; - unsigned lastNumSubPatterns : 30; - bool multiline : 1; - unsigned lastOvectorIndex : 1; -}; - RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype) : InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp")) , d(new RegExpConstructorPrivate) @@ -123,30 +101,6 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structur putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum); } -/* - To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular - expression matching through the performMatch function. We use cached results to calculate, - e.g., RegExp.lastMatch and RegExp.leftParen. -*/ -void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) -{ - position = r->match(s, startOffset, &d->tempOvector()); - - if (ovector) - *ovector = d->tempOvector().data(); - - if (position != -1) { - ASSERT(!d->tempOvector().isEmpty()); - - length = d->tempOvector()[1] - d->tempOvector()[0]; - - d->input = s; - d->lastInput = s; - d->changeLastOvector(); - d->lastNumSubPatterns = r->numSubpatterns(); - } -} - RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data) : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h index f8bccf4..f9ca9cf 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h @@ -22,6 +22,7 @@ #define RegExpConstructor_h #include "InternalFunction.h" +#include "RegExp.h" #include <wtf/OwnPtr.h> namespace JSC { @@ -30,13 +31,35 @@ namespace JSC { class RegExpPrototype; struct RegExpConstructorPrivate; + struct RegExpConstructorPrivate : FastAllocBase { + // Global search cache / settings + RegExpConstructorPrivate() + : lastNumSubPatterns(0) + , multiline(false) + , lastOvectorIndex(0) + { + } + + const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } + Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } + Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } + void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } + + UString input; + UString lastInput; + Vector<int, 32> ovector[2]; + unsigned lastNumSubPatterns : 30; + bool multiline : 1; + unsigned lastOvectorIndex : 1; + }; + class RegExpConstructor : public InternalFunction { public: RegExpConstructor(ExecState*, NonNullPassRefPtr<Structure>, RegExpPrototype*); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); @@ -59,6 +82,9 @@ namespace JSC { JSValue getLeftContext(ExecState*) const; JSValue getRightContext(ExecState*) const; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); @@ -78,6 +104,30 @@ namespace JSC { return static_cast<RegExpConstructor*>(asObject(value)); } + /* + To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular + expression matching through the performMatch function. We use cached results to calculate, + e.g., RegExp.lastMatch and RegExp.leftParen. + */ + inline void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) + { + position = r->match(s, startOffset, &d->tempOvector()); + + if (ovector) + *ovector = d->tempOvector().data(); + + if (position != -1) { + ASSERT(!d->tempOvector().isEmpty()); + + length = d->tempOvector()[1] - d->tempOvector()[0]; + + d->input = s; + d->lastInput = s; + d->changeLastOvector(); + d->lastNumSubPatterns = r->numSubpatterns(); + } + } + } // namespace JSC #endif // RegExpConstructor_h diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp index 877d7b6..679d072 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp @@ -159,7 +159,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args) } int position; - int length; + int length = 0; regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); if (position < 0) { d->lastIndex = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h index f5a9340..3117c86 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h @@ -49,9 +49,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: bool match(ExecState*, const ArgList&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h index 944f6ba..84e1ad2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h @@ -48,10 +48,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags; StringObject(NonNullPassRefPtr<Structure>, JSString*); }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index 0cba83d..69e1939 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h @@ -44,9 +44,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags; + virtual bool toBoolean(ExecState*) const { return false; } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp index b57732a..a0713b8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp @@ -25,6 +25,7 @@ #include "CachedCall.h" #include "Error.h" #include "Executable.h" +#include "JSGlobalObjectFunctions.h" #include "JSArray.h" #include "JSFunction.h" #include "ObjectPrototype.h" @@ -72,6 +73,10 @@ static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSVa static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*, JSObject*, JSValue, const ArgList&); + } #include "StringPrototype.lut.h" @@ -117,6 +122,9 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec fontsize stringProtoFuncFontsize DontEnum|Function 1 anchor stringProtoFuncAnchor DontEnum|Function 1 link stringProtoFuncLink DontEnum|Function 1 + trim stringProtoFuncTrim DontEnum|Function 0 + trimLeft stringProtoFuncTrimLeft DontEnum|Function 0 + trimRight stringProtoFuncTrimRight DontEnum|Function 0 @end */ @@ -249,7 +257,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue return jsNull(); while (true) { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -290,7 +298,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue } else { do { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -485,7 +493,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); if (!(reg->global())) { // case without 'g' flag is handled like RegExp.prototype.exec @@ -535,7 +543,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); return jsNumber(exec, pos); } @@ -899,4 +907,51 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th return jsNontrivialString(exec, UString(buffer, bufferSize, false)); } +enum { + TrimLeft = 1, + TrimRight = 2 +}; + +static inline bool isTrimWhitespace(UChar c) +{ + return isStrWhiteSpace(c) || c == 0x200b; +} + +static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind) +{ + UString str = thisValue.toThisString(exec); + int left = 0; + if (trimKind & TrimLeft) { + while (left < str.size() && isTrimWhitespace(str[left])) + left++; + } + int right = str.size(); + if (trimKind & TrimRight) { + while (right > left && isTrimWhitespace(str[right - 1])) + right--; + } + + // Don't gc allocate a new string if we don't have to. + if (left == 0 && right == str.size() && thisValue.isString()) + return thisValue; + + return jsString(exec, str.substr(left, right - left)); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft | TrimRight); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimRight); +} + + } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp index 7209b5f..a11050f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp @@ -28,9 +28,10 @@ #include "Identifier.h" #include "JSObject.h" +#include "JSPropertyNameIterator.h" +#include "Lookup.h" #include "PropertyNameArray.h" #include "StructureChain.h" -#include "Lookup.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/RefPtr.h> @@ -159,9 +160,9 @@ Structure::~Structure() m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); } - - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); + + if (m_enumerationCache) + m_enumerationCache->setCachedStructure(0); if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; @@ -282,59 +283,6 @@ void Structure::materializePropertyMap() } } -void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - getEnumerableNamesFromPropertyTable(propertyNames); - getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); -} - -void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); - - if (shouldCache && m_cachedPropertyNameArrayData) { - if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { - propertyNames.setData(m_cachedPropertyNameArrayData); - return; - } - clearEnumerationCache(); - } - - baseObject->getOwnPropertyNames(exec, propertyNames); - - if (m_prototype.isObject()) { - propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. - JSObject* prototype = asObject(m_prototype); - while(1) { - if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames); - break; - } - prototype->getOwnPropertyNames(exec, propertyNames); - JSValue nextProto = prototype->prototype(); - if (!nextProto.isObject()) - break; - prototype = asObject(nextProto); - } - } - - if (shouldCache) { - StructureChain* protoChain = prototypeChain(exec); - m_cachedPropertyNameArrayData = propertyNames.data(); - if (!protoChain->isCacheable()) - return; - m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain); - m_cachedPropertyNameArrayData->setCachedStructure(this); - } -} - -void Structure::clearEnumerationCache() -{ - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); - m_cachedPropertyNameArrayData.clear(); -} - void Structure::growPropertyStorageCapacity() { if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) @@ -598,25 +546,25 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = put(propertyName, attributes, specificValue); if (propertyStorageSize() > propertyStorageCapacity()) growPropertyStorageCapacity(); - clearEnumerationCache(); return offset; } size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { ASSERT(isUncacheableDictionary()); + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = remove(propertyName); - clearEnumerationCache(); return offset; } @@ -1057,7 +1005,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b) return 0; } -void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames) +void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -1114,25 +1062,6 @@ void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyN } } -void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) -{ - // Add properties from the static hashtables of properties - for (; classInfo; classInfo = classInfo->parentClass) { - const HashTable* table = classInfo->propHashTable(exec); - if (!table) - continue; - table->initializeIfNeeded(exec); - ASSERT(table->table); - - int hashSizeMask = table->compactSize - 1; - const HashEntry* entry = table->table; - for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && !(entry->attributes() & DontEnum)) - propertyNames.add(entry->key()); - } - } -} - #if DO_PROPERTYMAP_CONSTENCY_CHECK void Structure::checkConsistency() diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index ed9f6e5..2496c1b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -30,6 +30,8 @@ #include "JSType.h" #include "JSValue.h" #include "PropertyMapHashTable.h" +#include "PropertyNameArray.h" +#include "Protect.h" #include "StructureChain.h" #include "StructureTransitionTable.h" #include "JSTypeInfo.h" @@ -76,8 +78,6 @@ namespace JSC { ~Structure(); - void markAggregate(MarkStack&); - // These should be used with caution. size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t removePropertyWithoutTransition(const Identifier& propertyName); @@ -116,9 +116,6 @@ namespace JSC { return hasTransition(propertyName._ustring.rep(), attributes); } - void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } @@ -127,6 +124,10 @@ namespace JSC { JSCell* specificValue() { return m_specificValueInPrevious; } void despecifyDictionaryFunction(const Identifier& propertyName); + void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. + JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); } + void getEnumerablePropertyNames(PropertyNameArray&); + private: Structure(JSValue prototype, const TypeInfo&); @@ -140,8 +141,6 @@ namespace JSC { size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); void addAnonymousSlots(unsigned slotCount); - void getEnumerableNamesFromPropertyTable(PropertyNameArray&); - void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&); void expandPropertyMapHashTable(); void rehashPropertyMapHashTable(); @@ -162,8 +161,6 @@ namespace JSC { materializePropertyMap(); } - void clearEnumerationCache(); - signed char transitionCount() const { // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both. @@ -189,7 +186,7 @@ namespace JSC { StructureTransitionTable table; - RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; + ProtectedPtr<JSPropertyNameIterator> m_enumerationCache; PropertyMapHashTable* m_propertyTable; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp index 6e8a0ee..085876c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp @@ -46,18 +46,4 @@ StructureChain::StructureChain(Structure* head) m_vector[i] = 0; } -bool StructureChain::isCacheable() const -{ - uint32_t i = 0; - - while (m_vector[i]) { - // Both classes of dictionary structure may change arbitrarily so we can't cache them - if (m_vector[i]->isDictionary()) - return false; - if (!m_vector[i++]->typeInfo().hasDefaultGetPropertyNames()) - return false; - } - return true; -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h index c48749d..816b66d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h @@ -36,10 +36,11 @@ namespace JSC { class Structure; class StructureChain : public RefCounted<StructureChain> { + friend class JIT; + public: static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); } RefPtr<Structure>* head() { return m_vector.get(); } - bool isCacheable() const; private: StructureChain(Structure* head); diff --git a/src/3rdparty/webkit/JavaScriptCore/wscript b/src/3rdparty/webkit/JavaScriptCore/wscript index 9dd37c9..7a5ba1b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wscript +++ b/src/3rdparty/webkit/JavaScriptCore/wscript @@ -30,7 +30,7 @@ import commands from settings import * jscore_excludes = ['jsc.cpp', 'ucptable.cpp', 'GOwnPtr.cpp'] -jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp'])) +jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp'])) sources = [] diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h b/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h index 6a05211..f682f0d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/CrossThreadRefCounted.h @@ -70,10 +70,6 @@ namespace WTF { return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef()); } -#ifndef NDEBUG - bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); } -#endif - private: CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter) : m_threadSafeRefCounter(threadedCounter) @@ -92,6 +88,10 @@ namespace WTF { void threadSafeDeref(); +#ifndef NDEBUG + bool isOwnedByCurrentThread() const { return !m_threadId || m_threadId == currentThread(); } +#endif + RefCountedBase m_refCounter; ThreadSafeSharedBase* m_threadSafeRefCounter; T* m_data; @@ -103,7 +103,7 @@ namespace WTF { template<class T> void CrossThreadRefCounted<T>::ref() { - ASSERT(!m_threadId || m_threadId == currentThread()); + ASSERT(isOwnedByCurrentThread()); m_refCounter.ref(); #ifndef NDEBUG // Store the threadId as soon as the ref count gets to 2. @@ -119,7 +119,7 @@ namespace WTF { template<class T> void CrossThreadRefCounted<T>::deref() { - ASSERT(!m_threadId || m_threadId == currentThread()); + ASSERT(isOwnedByCurrentThread()); if (m_refCounter.derefBase()) { threadSafeDeref(); delete this; @@ -146,10 +146,12 @@ namespace WTF { template<class T> PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy() { + ASSERT(isOwnedByCurrentThread()); if (m_threadSafeRefCounter) m_threadSafeRefCounter->ref(); else m_threadSafeRefCounter = new ThreadSafeSharedBase(2); + return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp index a9472c9..6cd8ef0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.cpp @@ -379,6 +379,9 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #include <stdarg.h> #include <stddef.h> #include <stdio.h> +#if PLATFORM(UNIX) +#include <unistd.h> +#endif #if COMPILER(MSVC) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -391,6 +394,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #if PLATFORM(DARWIN) #include "MallocZoneSupport.h" #include <wtf/HashSet.h> +#include <wtf/Vector.h> #endif #ifndef PRIuS @@ -2274,7 +2278,7 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -#if PLATFORM(WIN) +#if PLATFORM(WIN_OS) static void sleep(unsigned seconds) { ::Sleep(seconds * 1000); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h index b23e7b0..ca0961c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/FastMalloc.h @@ -213,6 +213,9 @@ using WTF::fastMallocAllow; // debug-only code to make sure we don't use the system malloc via the default operator // new by accident. +// We musn't customize the global operator new and delete for the Qt port. +#if !PLATFORM(QT) + WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); } WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); } @@ -224,4 +227,6 @@ WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw( #endif +#endif + #endif /* WTF_FastMalloc_h */ diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h index d863226..8bf6447 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ListRefPtr.h @@ -44,6 +44,9 @@ namespace WTF { template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } }; + // Remove inline for winscw compiler to prevent the compiler agressively resolving + // T::ref() in RefPtr<T>'s copy constructor. The bug is reported at: + // https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812. template <typename T> #if !COMPILER(WINSCW) inline diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h index 324300d..556230e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h @@ -102,6 +102,8 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x #if COMPILER(MSVC) || COMPILER(RVCT) +inline long long llround(double num) { return static_cast<long long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } +inline long long llroundf(float num) { return static_cast<long long>(num > 0 ? num + 0.5f : ceil(num - 0.5f)); } inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); } inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h index 9fbfa85..7151b514 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h @@ -231,40 +231,94 @@ #if defined(arm) \ || defined(__arm__) #define WTF_PLATFORM_ARM 1 + #if defined(__ARMEB__) #define WTF_PLATFORM_BIG_ENDIAN 1 -#elif !defined(__ARM_EABI__) && !defined(__EABI__) && !defined(__VFP_FP__) + +#elif !defined(__ARM_EABI__) \ + && !defined(__EABI__) \ + && !defined(__VFP_FP__) #define WTF_PLATFORM_MIDDLE_ENDIAN 1 + #endif -#define ARM_ARCH_VERSION 3 -#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__MARM_ARMV4__) \ - || defined(_ARMV4I_) -#undef ARM_ARCH_VERSION + +/* Set ARM_ARCH_VERSION */ +#if defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) \ + || defined(__MARM_ARMV4__) \ + || defined(_ARMV4I_) #define ARM_ARCH_VERSION 4 -#endif -#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ - || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) || defined(__MARM_ARMV5__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) \ + || defined(__MARM_ARMV5__) #define ARM_ARCH_VERSION 5 -#endif -#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) || defined(__ARMV6__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARMV6__) #define ARM_ARCH_VERSION 6 -#endif -#if defined(__ARM_ARCH_7A__) -#undef ARM_ARCH_VERSION + +#elif defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) #define ARM_ARCH_VERSION 7 + +/* RVCT sets _TARGET_ARCH_ARM */ +#elif defined(__TARGET_ARCH_ARM) +#define ARM_ARCH_VERSION __TARGET_ARCH_ARM + +#else +#define ARM_ARCH_VERSION 0 + #endif + +/* Set THUMB_ARM_VERSION */ +#if defined(__ARM_ARCH_4T__) +#define THUMB_ARCH_VERSION 1 + +#elif defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +#define THUMB_ARCH_VERSION 2 + +#elif defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) +#define THUMB_ARCH_VERSION 3 + +#elif defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) +#define THUMB_ARCH_VERSION 4 + +/* RVCT sets __TARGET_ARCH_THUMB */ +#elif defined(__TARGET_ARCH_THUMB) +#define THUMB_ARCH_VERSION __TARGET_ARCH_THUMB + +#else +#define THUMB_ARCH_VERSION 0 +#endif + /* On ARMv5 and below the natural alignment is required. */ #if !defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_ARCH_VERSION <= 5 #define ARM_REQUIRE_NATURAL_ALIGNMENT 1 #endif + /* Defines two pseudo-platforms for ARM and Thumb-2 instruction set. */ #if !defined(WTF_PLATFORM_ARM_TRADITIONAL) && !defined(WTF_PLATFORM_ARM_THUMB2) -# if defined(thumb2) || defined(__thumb2__) +# if defined(thumb2) || defined(__thumb2__) \ + || ((defined(__thumb) || defined(__thumb__)) && THUMB_ARCH_VERSION == 4) # define WTF_PLATFORM_ARM_TRADITIONAL 0 # define WTF_PLATFORM_ARM_THUMB2 1 # elif PLATFORM_ARM_ARCH(4) @@ -805,6 +859,10 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WARN_UNUSED_RETURN #endif +#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((PLATFORM(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK))) +#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1 +#endif + /* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */ #define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp index 0e6e208..52fb130 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/RandomNumber.cpp @@ -82,6 +82,23 @@ double randomNumber() return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); #elif PLATFORM(WINCE) return genrand_res53(); +#elif PLATFORM(WIN_OS) + uint32_t part1 = rand() & (RAND_MAX - 1); + uint32_t part2 = rand() & (RAND_MAX - 1); + uint32_t part3 = rand() & (RAND_MAX - 1); + uint32_t part4 = rand() & (RAND_MAX - 1); + // rand only provides 15 bits on Win32 + uint64_t fullRandom = part1; + fullRandom <<= 15; + fullRandom |= part2; + fullRandom <<= 15; + fullRandom |= part3; + fullRandom <<= 15; + fullRandom |= part4; + + // Mask off the low 53bits + fullRandom &= (1LL << 53) - 1; + return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); #else uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h index 559e3f2..1120d65 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/StringExtras.h @@ -75,12 +75,12 @@ inline char* strdup(const char* strSource) inline int strncasecmp(const char* s1, const char* s2, size_t len) { - return strnicmp(s1, s2, len); + return _strnicmp(s1, s2, len); } inline int strcasecmp(const char* s1, const char* s2) { - return stricmp(s1, s2); + return _stricmp(s1, s2); } #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp index d777424..b635a45 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.cpp @@ -1400,14 +1400,6 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const } } -int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize) -{ - if (JSRegExp* fallback = jitObject.getFallback()) - return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0]; - - return jitObject.execute(input, start, length, output); -} - }} #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h index 5b0df9d..1872f21 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexJIT.h @@ -82,7 +82,14 @@ private: }; void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false); -int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize); + +inline int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize) +{ + if (JSRegExp* fallback = jitObject.getFallback()) + return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0]; + + return jitObject.execute(input, start, length, output); +} } } // namespace JSC::Yarr |