diff options
author | Steve Block <steveblock@google.com> | 2009-11-05 09:23:40 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-11-10 22:41:12 +0000 |
commit | cac0f67c402d107cdb10971b95719e2ff9c7c76b (patch) | |
tree | d182c7f87211c6f201a5f038e332336493ebdbe7 /JavaScriptCore | |
parent | 4b2ef0f288e7c6c4602f621b7a0e9feed304b70e (diff) | |
download | external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.zip external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.gz external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.bz2 |
Merge webkit.org at r50258 : Initial merge by git.
Change-Id: I1a9e1dc4ed654b69174ad52a4f031a07240f37b0
Diffstat (limited to 'JavaScriptCore')
134 files changed, 4111 insertions, 2010 deletions
diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h index b6d1532..b9167a8 100644 --- a/JavaScriptCore/API/APICast.h +++ b/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/JavaScriptCore/API/JSCallbackConstructor.h b/JavaScriptCore/API/JSCallbackConstructor.h index 202b119..c4bd7ad 100644 --- a/JavaScriptCore/API/JSCallbackConstructor.h +++ b/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/JavaScriptCore/API/JSCallbackFunction.h b/JavaScriptCore/API/JSCallbackFunction.h index 3a17fa2..0cf25c4 100644 --- a/JavaScriptCore/API/JSCallbackFunction.h +++ b/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/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h index 86f2f32..d19890a 100644 --- a/JavaScriptCore/API/JSCallbackObject.h +++ b/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/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp index c358a84..e6626b7 100644 --- a/JavaScriptCore/API/JSContextRef.cpp +++ b/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/JavaScriptCore/API/JSContextRefPrivate.h b/JavaScriptCore/API/JSContextRefPrivate.h new file mode 100644 index 0000000..ff014ec --- /dev/null +++ b/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/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c index 1f413e1..152babc 100644 --- a/JavaScriptCore/API/tests/testapi.c +++ b/JavaScriptCore/API/tests/testapi.c @@ -25,6 +25,7 @@ #include "JavaScriptCore.h" #include "JSBasePrivate.h" +#include "JSContextRefPrivate.h" #include <math.h> #define ASSERT_DISABLED 0 #include <wtf/Assertions.h> @@ -41,8 +42,8 @@ static double nan(const char*) #endif -static JSGlobalContextRef context = 0; -static int failed = 0; +static JSGlobalContextRef context; +static int failed; static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue) { if (JSValueToBoolean(context, value) != expectedValue) { @@ -618,14 +619,16 @@ static JSClassRef Derived_class(JSContextRef context) return jsClass; } -static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +static JSValueRef print_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { UNUSED_PARAM(functionObject); UNUSED_PARAM(thisObject); UNUSED_PARAM(exception); + + ASSERT(JSContextGetGlobalContext(ctx) == context); if (argumentCount > 0) { - JSStringRef string = JSValueToStringCopy(context, arguments[0], NULL); + JSStringRef string = JSValueToStringCopy(ctx, arguments[0], NULL); size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string); char* stringUTF8 = (char*)malloc(sizeUTF8); JSStringGetUTF8CString(string, stringUTF8, sizeUTF8); @@ -634,7 +637,7 @@ static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functio JSStringRelease(string); } - return JSValueMakeUndefined(context); + return JSValueMakeUndefined(ctx); } static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) @@ -760,6 +763,7 @@ int main(int argc, char* argv[]) JSGlobalContextRetain(context); JSGlobalContextRelease(context); + ASSERT(JSContextGetGlobalContext(context) == context); JSReportExtraMemoryCost(context, 0); JSReportExtraMemoryCost(context, 1); diff --git a/JavaScriptCore/AllInOneFile.cpp b/JavaScriptCore/AllInOneFile.cpp index 7b67dbe..e69de29 100644 --- a/JavaScriptCore/AllInOneFile.cpp +++ b/JavaScriptCore/AllInOneFile.cpp @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -// This file exists to help compile the essential code of -// JavaScriptCore all as one file, for compilers and build systems -// that see a significant speed gain from this. - -#define KDE_USE_FINAL 1 -#define JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE 1 -#include "config.h" - -// these headers are included here to avoid confusion between ::JSType and JSC::JSType -#include "JSCallbackConstructor.h" -#include "JSCallbackFunction.h" -#include "JSCallbackObject.h" - -#include "runtime/JSStaticScopeObject.cpp" -#include "runtime/JSFunction.cpp" -#include "runtime/Arguments.cpp" -#include "runtime/JSAPIValueWrapper.cpp" -#include "runtime/JSGlobalObjectFunctions.cpp" -#include "runtime/PrototypeFunction.cpp" -#include "runtime/GlobalEvalFunction.cpp" -#include "debugger/Debugger.cpp" -#include "runtime/JSArray.cpp" -#include "runtime/ArrayConstructor.cpp" -#include "runtime/ArrayPrototype.cpp" -#include "runtime/BooleanConstructor.cpp" -#include "runtime/BooleanObject.cpp" -#include "runtime/BooleanPrototype.cpp" -#include "runtime/Collector.cpp" -#include "runtime/CommonIdentifiers.cpp" -#include "runtime/DateConstructor.cpp" -#include "runtime/DateConversion.cpp" -#include "runtime/DatePrototype.cpp" -#include "runtime/DateInstance.cpp" -#include "wtf/dtoa.cpp" -#include "runtime/ErrorInstance.cpp" -#include "runtime/ErrorPrototype.cpp" -#include "runtime/ErrorConstructor.cpp" -#include "runtime/FunctionConstructor.cpp" -#include "runtime/FunctionPrototype.cpp" -#include "Grammar.cpp" -#include "runtime/Identifier.cpp" -#include "runtime/JSString.cpp" -#include "runtime/JSNumberCell.cpp" -#include "runtime/GetterSetter.cpp" -#include "runtime/InternalFunction.cpp" -#include "runtime/Completion.cpp" -#include "runtime/JSImmediate.cpp" -#include "runtime/JSLock.cpp" -#include "runtime/JSWrapperObject.cpp" -#include "parser/Lexer.cpp" -#include "runtime/ArgList.cpp" -#include "runtime/Lookup.cpp" -#include "runtime/MathObject.cpp" -#include "runtime/NativeErrorConstructor.cpp" -#include "runtime/NativeErrorPrototype.cpp" -#include "runtime/NumberConstructor.cpp" -#include "runtime/NumberObject.cpp" -#include "runtime/NumberPrototype.cpp" -#include "parser/Nodes.cpp" -#include "runtime/JSObject.cpp" -#include "runtime/Error.cpp" -#include "runtime/JSGlobalObject.cpp" -#include "runtime/ObjectConstructor.cpp" -#include "runtime/ObjectPrototype.cpp" -#include "runtime/Operations.cpp" -#include "parser/Parser.cpp" -#include "runtime/PropertySlot.cpp" -#include "runtime/PropertyNameArray.cpp" -#include "runtime/RegExp.cpp" -#include "runtime/RegExpConstructor.cpp" -#include "runtime/RegExpObject.cpp" -#include "runtime/RegExpPrototype.cpp" -#include "runtime/ScopeChain.cpp" -#include "runtime/StringConstructor.cpp" -#include "runtime/StringObject.cpp" -#include "runtime/StringPrototype.cpp" -#include "runtime/UString.cpp" -#include "runtime/JSValue.cpp" -#include "runtime/CallData.cpp" -#include "runtime/ConstructData.cpp" -#include "runtime/JSCell.cpp" -#include "runtime/JSVariableObject.cpp" -#include "wtf/FastMalloc.cpp" -#include "wtf/TCSystemAlloc.cpp" -#include "bytecompiler/BytecodeGenerator.cpp" -#include "interpreter/RegisterFile.cpp" diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 7cf56bd..fb09372 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,1325 @@ +2009-10-28 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + JSC JIT on ARMv7 cannot link jumps >16Mb range + https://bugs.webkit.org/show_bug.cgi?id=30891 + + Start planing all relative jumps as move-32-bit-immediate-to-register-BX. + In the cases where the jump would fall within a relative jump range, use a relative jump. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::~ARMv7Assembler): + (JSC::ARMv7Assembler::LinkRecord::LinkRecord): + (JSC::ARMv7Assembler::): + (JSC::ARMv7Assembler::executableCopy): + (JSC::ARMv7Assembler::linkJump): + (JSC::ARMv7Assembler::relinkJump): + (JSC::ARMv7Assembler::setInt32): + (JSC::ARMv7Assembler::isB): + (JSC::ARMv7Assembler::isBX): + (JSC::ARMv7Assembler::isMOV_imm_T3): + (JSC::ARMv7Assembler::isMOVT): + (JSC::ARMv7Assembler::isNOP_T1): + (JSC::ARMv7Assembler::isNOP_T2): + (JSC::ARMv7Assembler::linkJumpAbsolute): + (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst): + (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond): + (JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp5i6Imm4Reg4EncodedImm): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::makeJump): + (JSC::MacroAssemblerARMv7::makeBranch): + * jit/JIT.h: + * wtf/Platform.h: + +2009-10-28 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Improve for..in enumeration performance + https://bugs.webkit.org/show_bug.cgi?id=30887 + + Improve indexing of an object with a for..in iterator by + identifying cases where get_by_val is being used with a iterator + as the subscript and replace it with a new get_by_pname + bytecode. get_by_pname then optimizes lookups that directly access + the base object. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetByVal): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::pushOptimisedForIn): + (JSC::BytecodeGenerator::popOptimisedForIn): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::emit_op_get_by_pname): + (JSC::JIT::emitSlow_op_get_by_pname): + * parser/Nodes.cpp: + (JSC::ForInNode::emitBytecode): + * runtime/JSObject.h: + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::getOffset): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + * runtime/JSValue.h: + (JSC::JSValue::): + * runtime/Structure.cpp: + (JSC::Structure::addPropertyTransition): + (JSC::Structure::changePrototypeTransition): + (JSC::Structure::despecifyFunctionTransition): + (JSC::Structure::addAnonymousSlotsTransition): + (JSC::Structure::getterSetterTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::addPropertyWithoutTransition): + Track the existence (or not) of non-enumerable properties. + * runtime/Structure.h: + (JSC::Structure::propertyStorageCapacity): + (JSC::Structure::propertyStorageSize): + (JSC::Structure::hasNonEnumerableProperties): + (JSC::Structure::hasAnonymousSlots): + +2009-10-28 Dmitry Titov <dimich@chromium.org> + + Not reviewed, attemp to fix Windows build. + + Touch the cpp file to cause recompile. + + * wtf/Threading.cpp: + (WTF::threadEntryPoint): + +2009-10-28 Dmitry Titov <dimich@chromium.org> + + Reviewed by David Levin. + + https://bugs.webkit.org/show_bug.cgi?id=30805 + Add MessageQueue::removeIf(Predicate&) to remove certain tasks without pulling them from the queue. + Existing Database tests cover this since Database removes tasks when it is stopped. + + * wtf/MessageQueue.h: + (WTF::::removeIf): + +2009-10-28 Afonso R. Costa Jr. <afonso.costa@openbossa.org> + + Reviewed by Oliver Hunt. + + [Qt] Enable YARR when YARR_JIT is enabled + https://bugs.webkit.org/show_bug.cgi?id=30730 + + When enabling or disabling JIT using JAVASCRIPTCORE_JIT, the ENABLE_YARR should + be toggled also. + + * JavaScriptCore.pri: + +2009-10-24 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Oliver Hunt. + + Fix strict aliasing warning by switching reinterpret_cast to bitwise_cast. + + strict-aliasing warnings in JSFunction.h + https://bugs.webkit.org/show_bug.cgi?id=27869 + + * runtime/JSFunction.h: + (JSC::JSFunction::nativeFunction): + (JSC::JSFunction::scopeChain): + (JSC::JSFunction::setScopeChain): + (JSC::JSFunction::setNativeFunction): + +2009-10-28 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Build-fix for 64-bit Windows + + * wtf/Platform.h: Make sure to use WTF_USE_JSVALUE64 + +2009-10-28 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix!). + + * jit/JIT.h: + +2009-10-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Rubber-stamped by Darin Adler. + + Export fastMalloc, fastCalloc, fastRealloc and fastFree on GCC/Unix + https://bugs.webkit.org/show_bug.cgi?id=30769 + + When using -fvisibility=hidden to hide all internal symbols by default + the malloc symbols will be hidden as well. For memory instrumentation + it is needed to provide an instrumented version of these symbols and + override the normal routines and by changing the visibility back to + default this becomes possible. + + The only other solution would be to use system malloc instead of the + TCmalloc implementation but this will not allow to analyze memory + behavior with the default allocator. + + * wtf/FastMalloc.h: Define WTF_FAST_MALLOC_EXPORT for GCC and !darwin + +2009-10-27 Gavin Barraclough <barraclough@apple.com> + + Rubber Stamped by Samuel Q. Weinig. + + Make the asserts protecting the offsets in the JIT more descriptive. + + * jit/JIT.h: + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::compileGetByIdSlowCase): + (JSC::JIT::emit_op_put_by_id): + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + A little bit of refactoring in the date code. + + * JavaScriptCore.exp: Don't export this unused symbol. + + * runtime/DateConstructor.cpp: + (JSC::constructDate): + + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + * runtime/DateInstance.h: Removed some unused functions. Changed the default + constructor to ensure that a DateInstance is always initialized. + + * runtime/DatePrototype.cpp: + (JSC::DatePrototype::DatePrototype): Pass an initializer to our constructor, + since it now requires one. + + * wtf/DateMath.cpp: + (WTF::msToGregorianDateTime): Only compute our offset from UTC if our + output will require it. Otherwise, our offset is 0. + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Build fix: Mark DateInstaceCache.h private, so other frameworks can see it. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Build fix: re-readded this file. + + * runtime/DateInstanceCache.h: Added. + (JSC::DateInstanceData::create): + (JSC::DateInstanceData::DateInstanceData): + (JSC::DateInstanceCache::DateInstanceCache): + (JSC::DateInstanceCache::add): + (JSC::DateInstanceCache::lookup): + +2009-10-27 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Darin Adler and Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=30800 + Cache recently computed date data. + + SunSpider reports a ~0.5% speedup, mostly from date-format-tofte.js. + + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: Added new file. + + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + (JSC::DateInstance::getGregorianDateTime): Use the shared cache. + + * runtime/DateInstance.h: Renamed m_cache to m_data, to avoid the confusion + of a "cache cache". + + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToISOString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncGetFullYear): + (JSC::dateProtoFuncGetUTCFullYear): + (JSC::dateProtoFuncToGMTString): + (JSC::dateProtoFuncGetMonth): + (JSC::dateProtoFuncGetUTCMonth): + (JSC::dateProtoFuncGetDate): + (JSC::dateProtoFuncGetUTCDate): + (JSC::dateProtoFuncGetDay): + (JSC::dateProtoFuncGetUTCDay): + (JSC::dateProtoFuncGetHours): + (JSC::dateProtoFuncGetUTCHours): + (JSC::dateProtoFuncGetMinutes): + (JSC::dateProtoFuncGetUTCMinutes): + (JSC::dateProtoFuncGetSeconds): + (JSC::dateProtoFuncGetUTCSeconds): + (JSC::dateProtoFuncGetTimezoneOffset): + (JSC::setNewValueFromTimeArgs): + (JSC::setNewValueFromDateArgs): + (JSC::dateProtoFuncSetYear): + (JSC::dateProtoFuncGetYear): Pass an ExecState to these functions, so they + can access the DateInstanceCache. + + * runtime/JSGlobalData.h: Keep a DateInstanceCache. + +2009-10-27 James Robinson <jamesr@chromium.org> + + Reviewed by Darin Fisher. + + Ensures that JavaScriptCore/wtf/CurrentTime.cpp is not built in PLATFORM(CHROMIUM) builds. + + Chromium uses a different method to calculate the current time than is used in + JavaScriptCore/wtf/CurrentTime.cpp. This can lead to time skew when calls to currentTime() and Chromium's time + function are mixed. In particular, timers can get scheduled in the past which leads to 100% CPU use. + See http://code.google.com/p/chromium/issues/detail?id=25892 for an example. + + https://bugs.webkit.org/show_bug.cgi?id=30833 + + * JavaScriptCore.gyp/JavaScriptCore.gyp: + * wtf/CurrentTime.cpp: + +2009-10-27 Peter Varga <pvarga@inf.u-szeged.hu> + + Rubber-stamped by Tor Arne Vestbø. + + Fix typo in RegexInterpreter.cpp and RegexJIT.cpp alterantive to + alternative. + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::ByteCompiler::alternativeBodyDisjunction): + (JSC::Yarr::ByteCompiler::alternativeDisjunction): + (JSC::Yarr::ByteCompiler::emitDisjunction): + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateDisjunction): + +2009-10-26 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + Make .rc files compile on Windows without depending on MFC headers + https://bugs.webkit.org/show_bug.cgi?id=30750 + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: Use + winresrc.h because it exists even when MFC is not installed, and is + all that's needed here. + +2009-10-26 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Gavin Barraclough. + + The thunkReturnAddress is on JITStackFrame on ARM JIT as well + https://bugs.webkit.org/show_bug.cgi?id=30782 + + Move the thunkReturnAddress from top of the stack into the JITStackFrame + structure. This is a requirement for JSValue32_64 support on ARM. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::ret): Return with link register + (JSC::MacroAssemblerARM::prepareCall): Store the return address in link register + * jit/JIT.h: Remove unused ctiReturnRegister + * jit/JITInlineMethods.h: Same as ARMv7 + (JSC::JIT::restoreArgumentReference): Ditto. + (JSC::JIT::restoreArgumentReferenceForTrampoline): Ditto. + * jit/JITOpcodes.cpp: Remove ctiReturnRegister related instruction + * jit/JITStubs.cpp: Store thunkReturnAddress on JITStackFrame. Use + small trampoline functions which handle return addresses for each + CTI_STUB_FUNCTION. + * jit/JITStubs.h: Store thunkReturnAddress on JITStackFrame + (JSC::JITStackFrame::returnAddressSlot): Return with the address of thunkReturnAddress + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): Remove the unnecessary instruction + +2009-10-26 Steve Block <steveblock@google.com> + + Reviewed by Darin Adler. + + Adds ability to disable ReadWriteLock on platforms (eg Android) that use pthreads but do not support pthread_rwlock. + https://bugs.webkit.org/show_bug.cgi?id=30713 + + * wtf/Platform.h: Modified. Defines HAVE_PTHREAD_RWLOCK for all platforms currently using pthreads. + * wtf/Threading.h: Modified. Use pthread_rwlock_t only when HAVE_PTHREAD_RWLOCK is defined. + * wtf/ThreadingPthreads.cpp: Modified. Build ReadWriteLock methods only when HAVE_PTHREAD_RWLOCK is defined. + +2009-10-24 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Holger Freyther. + + [Qt] [Symbian] Set the capability and memory required to run QtWebKit for Symbian + https://bugs.webkit.org/show_bug.cgi?id=30476 + + Assign ReadUserData WriteUserData NetworkServices Symbian capabilities + to jsc.exe. + + * jsc.pro: + +2009-10-23 Steve Block <steveblock@google.com> + + Reviewed by Dmitry Titov. + + Fixes a leak in createThreadInternal on Android. + https://bugs.webkit.org/show_bug.cgi?id=30698 + + * wtf/ThreadingPthreads.cpp: Modified. + (WTF::createThreadInternal): Avoid leaking a ThreadData object on failure. + +2009-10-22 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Alexey Proskuryakov. + + Fixed ASSERT when opening Safari's Caches window while the Web Inspector + is open. + + * runtime/Collector.cpp: + (JSC::typeName): Added two new types to the type name list in the Collector. + These types have been around for a while, but nobody remembered to consider them here. + + * runtime/JSCell.h: + (JSC::JSCell::isPropertyNameIterator): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::isPropertyNameIterator): Give the Collector + a way to tell if a cell is a JSPropertyNameIterator. + +2009-10-22 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Jon Honeycutt. + + https://bugs.webkit.org/show_bug.cgi?id=30686 + Remove debug-specific def file. + Only Debug_All target uses JavaScriptCore_debug.dll naming, and since + that target is only used internally, maintaining two files just to + suppress a single link warning isn't worthwhile. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Removed. + +2009-10-21 Jon Honeycutt <jhoneycutt@apple.com> + + <rdar://problem/7270320> Screenshots of off-screen plug-ins are blank + <rdar://problem/7270314> After halting a transparent PluginView on + Windows, the transparency is applied twice + + Reviewed by Dan Bernstein. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + Export WTF::deleteOwnedPtr(HDC). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + Ditto. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: updated variable name. + + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Mark Rowe. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): Slightly tweaked this #ifdef to match the + size of a JSValue because m_jsStrings is an array of JSValues. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Mark Rowe. + + Fixed a 64-bit regression caused by the fix for + https://bugs.webkit.org/show_bug.cgi?id=30570. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): Use TimesEight stepping on 64-bit, since + 64-bit pointers are eight bytes long. + +2009-10-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Refactored DateInstance::msToGregorianDateTime so that a DateInstance's + caller doesn't need to supply the DateInstance's own internal value to + the DateInstance. + + * runtime/DateInstance.cpp: + (JSC::DateInstance::getGregorianDateTime): Renamed from "msToGregorianDateTime". + + * runtime/DateInstance.h: + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToISOString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncToLocaleString): + (JSC::dateProtoFuncToLocaleDateString): + (JSC::dateProtoFuncToLocaleTimeString): + (JSC::dateProtoFuncGetTime): + (JSC::dateProtoFuncGetFullYear): + (JSC::dateProtoFuncGetUTCFullYear): + (JSC::dateProtoFuncToGMTString): + (JSC::dateProtoFuncGetMonth): + (JSC::dateProtoFuncGetUTCMonth): + (JSC::dateProtoFuncGetDate): + (JSC::dateProtoFuncGetUTCDate): + (JSC::dateProtoFuncGetDay): + (JSC::dateProtoFuncGetUTCDay): + (JSC::dateProtoFuncGetHours): + (JSC::dateProtoFuncGetUTCHours): + (JSC::dateProtoFuncGetMinutes): + (JSC::dateProtoFuncGetUTCMinutes): + (JSC::dateProtoFuncGetSeconds): + (JSC::dateProtoFuncGetUTCSeconds): + (JSC::dateProtoFuncGetTimezoneOffset): + (JSC::setNewValueFromTimeArgs): + (JSC::setNewValueFromDateArgs): + (JSC::dateProtoFuncSetYear): + (JSC::dateProtoFuncGetYear): Also renamed "utc" to "outputIsUTC", for clarity. + +2009-10-20 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Geoffrey Garen. + + The op_next_pname should use 4 bytes addressing mode in case of JSValue32 + https://bugs.webkit.org/show_bug.cgi?id=30570 + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_next_pname): + +2009-10-20 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Oliver Hunt. + + Move OverridesMarkChildren flag from DatePrototype to its parent class + https://bugs.webkit.org/show_bug.cgi?id=30372 + + * runtime/DateInstance.h: + (JSC::DateInstance::createStructure): + * runtime/DatePrototype.h: + +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some put_by_id_transition code generation. + https://bugs.webkit.org/show_bug.cgi?id=30539 + + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::testPrototype): + (JSC::JIT::privateCompilePutByIdTransition): No need to do object type + checks or read Structures and prototypes from objects: they're all known + constants at compile time. + +2009-10-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Added a private API for getting a global context from a context, for + clients who want to preserve a context for a later callback. + + * API/APICast.h: + (toGlobalRef): Added an ASSERT, since this function is used more often + than before. + + * API/JSContextRef.cpp: + * API/JSContextRefPrivate.h: Added. The new API. + + * API/tests/testapi.c: + (print_callAsFunction): + (main): Test the new API. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: Build and export the new API. + +2009-10-17 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Tightened up some instanceof code generation. + https://bugs.webkit.org/show_bug.cgi?id=30488 + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): No need to do object type checks - + cell type checks and ImplementsDefaultHasIntance checks implicitly + supersede object type checks. + +2009-10-18 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Darin Adler. + + Use _stricmp and _strnicmp instead of deprecated stricmp and strnicmp. + https://bugs.webkit.org/show_bug.cgi?id=30474 + + stricmp and strnicmp are deprecated beginning in Visual + C++ 2005. Use _stricmp and _strnicmp instead in StringExtras.h. + + * wtf/StringExtras.h: + (strncasecmp): + (strcasecmp): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: apparently we shouldn't export those symbols? + + * JavaScriptCore.exp: + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Build fix: export some symbols. + + * JavaScriptCore.exp: + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + structure typeinfo flags should be inherited. + https://bugs.webkit.org/show_bug.cgi?id=30468 + + Add StructureFlag constant to the various JSC classes and use + it for the TypeInfo construction. This allows us to simply + accumulate flags by basing each classes StructureInfo on its parents. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSByteArray.h: + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-16 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fast for-in enumeration: Cache JSPropertyNameIterator; cache JSStrings + in JSPropertyNameIterator; inline more code. + + 1.024x as fast on SunSpider (fasta: 1.43x as fast). + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetPropertyNames): + (JSC::BytecodeGenerator::emitNextPropertyName): + * bytecompiler/BytecodeGenerator.h: Added a few extra operands to + op_get_pnames and op_next_pname so that we can track iteration state + in the register file instead of in the JSPropertyNameIterator. (To be + cacheable, the JSPropertyNameIterator must be stateless.) + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::Interpreter::privateExecute): Updated for in-RegisterFile + iteration state tracking. + + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + * jit/JIT.h: + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_pnames): Updated for in-RegisterFile + iteration state tracking. + + (JSC::JIT::emit_op_next_pname): Inlined code generation for op_next_pname. + + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): Updated for rename to + "normalizePrototypeChain" and removal of "isCacheable". + + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + (JSC::): Added has_property and to_object stubs. Removed op_next_pname + stub, since has_property is all we need anymore. + + * parser/Nodes.cpp: + (JSC::ForInNode::emitBytecode): Updated for in-RegisterFile + iteration state tracking. + + * runtime/JSCell.h: + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): Don't do caching at this layer + anymore, since we don't create a JSPropertyNameIterator at this layer. + + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): Do do caching at this layer. + (JSC::JSPropertyNameIterator::get): Updated for in-RegisterFile + iteration state tracking. + (JSC::JSPropertyNameIterator::markChildren): Mark our JSStrings. + + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::size): + (JSC::JSPropertyNameIterator::setCachedStructure): + (JSC::JSPropertyNameIterator::cachedStructure): + (JSC::JSPropertyNameIterator::setCachedPrototypeChain): + (JSC::JSPropertyNameIterator::cachedPrototypeChain): + (JSC::JSPropertyNameIterator::JSPropertyNameIterator): + (JSC::Structure::setEnumerationCache): Don't store iteration state in + a JSPropertyNameIterator. Do cache a JSPropertyNameIterator in a + Structure. + + * runtime/JSValue.h: + (JSC::asCell): + * runtime/MarkStack.h: Make those mischievous #include gods happy. + + * runtime/ObjectConstructor.cpp: + + * runtime/Operations.h: + (JSC::normalizePrototypeChain): Renamed countPrototypeChainEntriesAndCheckForProxies + to normalizePrototypeChain, since it changes dictionary prototypes to + non-dictionary objects. + + * runtime/PropertyNameArray.cpp: + (JSC::PropertyNameArray::add): + * runtime/PropertyNameArray.h: + (JSC::PropertyNameArrayData::PropertyNameArrayData): + (JSC::PropertyNameArray::data): + (JSC::PropertyNameArray::size): + (JSC::PropertyNameArray::begin): + (JSC::PropertyNameArray::end): Simplified some code here to help with + current and future refactoring. + + * runtime/Protect.h: + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::removePropertyWithoutTransition): No need to clear + the enumeration cache with adding / removing properties without + transition. It is an error to add / remove properties without transition + once an object has been observed, and we can ASSERT to catch that. + + * runtime/Structure.h: + (JSC::Structure::enumerationCache): Changed the enumeration cache to + hold a JSPropertyNameIterator. + + * runtime/StructureChain.cpp: + * runtime/StructureChain.h: + (JSC::StructureChain::head): Removed StructureChain::isCacheable because + it was wrong-headed in two ways: (1) It gave up when a prototype was a + dictionary, but instead we want un-dictionary heavily accessed + prototypes; (2) It folded a test for hasDefaultGetPropertyNames() into + a generic test for "cacheable-ness", but hasDefaultGetPropertyNames() + is only releavant to for-in caching. + +2009-10-16 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Adam Roben. + + Add a Debug_All configuration to build entire stack as debug. + Change Debug_Internal to: + - stop using _debug suffix for all WebKit/Safari binaries + - not use _debug as a DLL naming suffix + - use non-debug C runtime lib. + + * JavaScriptCore.vcproj/JavaScriptCore.make: Debug build in makefile should build Debug_All. + * JavaScriptCore.vcproj/JavaScriptCore.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Renamed single configuration from "Release" to "all". + * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Add Debug_All configuration. + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/jsc/jsc.vcproj: Add Debug_All configuration. + * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add Debug_All configuration. + +2009-10-16 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Last part -- replace HasDefaultGetPropertyNames with OverridesGetPropertyNames + flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetPropertyNames): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-10-16 Kevin Ollivier <kevino@theolliviers.com> + + wxMSW build fix, we can't use the simple hash there because the PlatformModuleVersion + structure differs. + + * wtf/Platform.h: + +2009-10-16 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement ExecutableAllocator for Symbian + https://bugs.webkit.org/show_bug.cgi?id=29946 + + Tested with YARR JIT enabled for Symbian; + This patch does not (yet) enable YARR JIT by default. + + * JavaScriptCore.pri: + * jit/ExecutableAllocator.h: + * jit/ExecutableAllocatorSymbian.cpp: Added. + (JSC::ExecutableAllocator::intializePageSize): + (JSC::ExecutablePool::systemAlloc): + (JSC::ExecutablePool::systemRelease): + +2009-10-15 Oliver Hunt <oliver@apple.com> + + Reviewed by Darin Adler. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 2 -- Reverse the TypeInfo HasDefaultMark flag to OverridesMarkChildren, etc + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GetterSetter.h: + (JSC::GetterSetter::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + (JSC::MarkStack::markChildren): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesMarkChildren): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Make typeinfo flags default to false + https://bugs.webkit.org/show_bug.cgi?id=30372 + + Part 1. Reverse the HasStandardGetOwnPropertySlot flag. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + (JSC::JSCell::fastGetOwnPropertySlot): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::JSString::createStructure): + * runtime/JSTypeInfo.h: + (JSC::TypeInfo::overridesGetOwnPropertySlot): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> +2009-10-14 Darin Adler <darin@apple.com> + + Additions so fix for https://bugs.webkit.org/show_bug.cgi?id=18994 + can build on Windows. + + * wtf/MathExtras.h: Added llround and llroundf for Windows. + +2009-10-14 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Set ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH for plugins while we're still building stubs. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + Refactor ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + https://bugs.webkit.org/show_bug.cgi?id=30278 + + Move the definition of ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH + from the make system into common code. + + * wtf/Platform.h: + +2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Darin Adler. + + ARM compiler does not understand reinterpret_cast<void*> + https://bugs.webkit.org/show_bug.cgi?id=29034 + + Change reinterpret_cast<void*> to regular C style (void*) cast + for the ARM RVCT compiler. + + * assembler/MacroAssemblerCodeRef.h: + (JSC::FunctionPtr::FunctionPtr): + * jit/JITOpcodes.cpp: Cast to FunctionPtr first + instead of directly casting to reinterpret_cast + * jit/JITStubCall.h: Ditto + change the type of m_stub + from void* to FunctionPtr. + (JSC::JITStubCall::JITStubCall): + (JSC::JITStubCall::call): + * jit/JITStubs.cpp: Ditto. + (JSC::DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)): + +2009-10-11 Oliver Hunt <oliver@apple.com> + + Re-enable the JIT. + + * wtf/Platform.h: + +2009-10-10 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + Support for String.trim(), String.trimLeft() and String.trimRight() methods + https://bugs.webkit.org/show_bug.cgi?id=26590 + + Implement trim, trimLeft, and trimRight + + * runtime/StringPrototype.cpp: + (JSC::isTrimWhitespace): + Our normal string whitespace function does not include U+200B which + is needed for compatibility with mozilla's implementation of trim. + U+200B does not appear to be expected according to spec, however I am + choosing to be lax, and match mozilla behavior so have added this + exception. + (JSC::trimString): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Eliminated some legacy bytecode weirdness. + + Use vPC[x] subscripting instead of ++vPC to access instruction operands. + This is simpler, and often more efficient. + + To support this, and to remove use of hard-coded offsets in bytecode and + JIT code generation and dumping, calculate jump offsets from the beginning + of an instruction, rather than the middle or end. + + Also, use OPCODE_LENGTH instead of hard-coded constants for the sizes of + opcodes. + + SunSpider reports no change in JIT mode, and a 1.01x speedup in Interpreter + mode. + + * bytecode/CodeBlock.cpp: + (JSC::printConditionalJump): + (JSC::CodeBlock::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitJump): + (JSC::BytecodeGenerator::emitJumpIfTrue): + (JSC::BytecodeGenerator::emitJumpIfFalse): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply): + (JSC::BytecodeGenerator::emitComplexJumpScopes): + (JSC::BytecodeGenerator::emitJumpScopes): + (JSC::BytecodeGenerator::emitNextPropertyName): + (JSC::BytecodeGenerator::emitCatch): + (JSC::BytecodeGenerator::emitJumpSubroutine): + (JSC::prepareJumpTableForImmediateSwitch): + (JSC::prepareJumpTableForCharacterSwitch): + (JSC::prepareJumpTableForStringSwitch): + (JSC::BytecodeGenerator::endSwitch): + * bytecompiler/Label.h: + (JSC::Label::setLocation): + (JSC::Label::bind): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolve): + (JSC::Interpreter::resolveSkip): + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::resolveBase): + (JSC::Interpreter::resolveBaseAndProperty): + (JSC::Interpreter::createExceptionScope): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_jnless): + (JSC::JIT::emitSlow_op_jnless): + (JSC::JIT::emit_op_jnlesseq): + (JSC::JIT::emitSlow_op_jnlesseq): + (JSC::JIT::emitBinaryDoubleOp): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jmp): + (JSC::JIT::emit_op_loop): + (JSC::JIT::emit_op_loop_if_less): + (JSC::JIT::emitSlow_op_loop_if_less): + (JSC::JIT::emit_op_loop_if_lesseq): + (JSC::JIT::emitSlow_op_loop_if_lesseq): + (JSC::JIT::emit_op_loop_if_true): + (JSC::JIT::emitSlow_op_loop_if_true): + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emitSlow_op_jfalse): + (JSC::JIT::emit_op_jtrue): + (JSC::JIT::emitSlow_op_jtrue): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_jneq_ptr): + (JSC::JIT::emit_op_jsr): + (JSC::JIT::emit_op_next_pname): + (JSC::JIT::emit_op_jmp_scopes): + +2009-10-09 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Migrated some code that didn't belong out of Structure. + + SunSpider says maybe 1.03x faster. + + * runtime/JSCell.h: Nixed Structure::markAggregate, and made marking of + a Structure's prototype the direct responsility of the object using it. + (Giving Structure a mark function was misleading because it implied that + all live structures get marked during GC, when they don't.) + + * runtime/JSGlobalObject.cpp: + (JSC::markIfNeeded): + (JSC::JSGlobalObject::markChildren): Added code to mark prototypes stored + on the global object. Maybe this wasn't necessary, but now we don't have + to wonder. + + * runtime/JSObject.cpp: + (JSC::JSObject::getPropertyNames): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::getEnumerableNamesFromClassInfoTable): + * runtime/JSObject.h: + (JSC::JSObject::markChildrenDirect): + * runtime/PropertyNameArray.h: + * runtime/Structure.cpp: + * runtime/Structure.h: + (JSC::Structure::setEnumerationCache): + (JSC::Structure::enumerationCache): Moved property name gathering code + from Structure to JSObject because having a Structure iterate its JSObject + was a layering violation. A JSObject is implemented using a Structure; not + the other way around. + +2009-10-09 Mark Rowe <mrowe@apple.com> + + Attempt to fix the GTK release build. + + * GNUmakefile.am: Include Grammar.cpp in release builds now that + AllInOneFile.cpp is gone. + +2009-10-09 Gabor Loki <loki@inf.u-szeged.hu> + + Rubber-stamped by Eric Seidel. + + Add ARM JIT support for Gtk port (disabled by default) + https://bugs.webkit.org/show_bug.cgi?id=30228 + + * GNUmakefile.am: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: added a few more variable initializations. + + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncSearch): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Qt build fix: added missing #include. + + * jsc.cpp: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: initialize variable whose initialization the compiler + can't otherwise figure out. + + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: updated exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Tiger build fix: fixed file name case. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-10-08 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Maciej Stachowiak. + + At long last, I pronounce the death of AllInOneFile.cpp. + + SunSpider reports a 1.01x speedup. + + * AllInOneFile.cpp: Removed. + * GNUmakefile.am: + * JavaScriptCore.exp: + * JavaScriptCore.gypi: + * JavaScriptCore.xcodeproj/project.pbxproj: Added missing project files + to compilation stages. + + * parser/Grammar.y: + * parser/Lexer.cpp: + * parser/Lexer.h: + (JSC::jscyylex): + * runtime/ArrayConstructor.cpp: + (JSC::constructArrayWithSizeQuirk): + * runtime/Collector.h: + * runtime/JSCell.cpp: + (JSC::JSCell::operator new): + * runtime/JSCell.h: + (JSC::JSCell::operator new): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::operator new): + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::operator new): + * runtime/JSString.cpp: + * runtime/JSString.h: + (JSC::jsString): + (JSC::jsSubstring): + (JSC::jsOwnedString): + * runtime/RegExpConstructor.cpp: + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructorPrivate::RegExpConstructorPrivate): + (JSC::RegExpConstructorPrivate::lastOvector): + (JSC::RegExpConstructorPrivate::tempOvector): + (JSC::RegExpConstructorPrivate::changeLastOvector): + (JSC::RegExpConstructor::performMatch): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncMatch): + * yarr/RegexJIT.cpp: + * yarr/RegexJIT.h: + (JSC::Yarr::executeRegex): Inlined a few things that Shark said + were hot, on the presumption that AllInOneFile.cpp used to inline them + automatically. + 2009-10-08 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> Reviewed by Gavin Barraclough. diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig index db89a7b..c338eb7 100644 --- a/JavaScriptCore/Configurations/Base.xcconfig +++ b/JavaScriptCore/Configurations/Base.xcconfig @@ -106,3 +106,4 @@ HAVE_DTRACE_macosx_ = $(HAVE_DTRACE_macosx_1040); HAVE_DTRACE_macosx_1040 = 0; HAVE_DTRACE_macosx_1050 = 0; HAVE_DTRACE_macosx_1060 = 1; +HAVE_DTRACE_macosx_1070 = 1; diff --git a/JavaScriptCore/Configurations/DebugRelease.xcconfig b/JavaScriptCore/Configurations/DebugRelease.xcconfig index 3b8651c..cbb0c8b 100644 --- a/JavaScriptCore/Configurations/DebugRelease.xcconfig +++ b/JavaScriptCore/Configurations/DebugRelease.xcconfig @@ -31,6 +31,7 @@ ARCHS_macosx_ = $(ARCHS_macosx_1040); ARCHS_macosx_1040 = $(NATIVE_ARCH); ARCHS_macosx_1050 = $(NATIVE_ARCH); ARCHS_macosx_1060 = $(ARCHS_STANDARD_32_64_BIT); +ARCHS_macosx_1070 = $(ARCHS_STANDARD_32_64_BIT); ONLY_ACTIVE_ARCH = YES; @@ -39,6 +40,7 @@ MACOSX_DEPLOYMENT_TARGET_ = 10.4; MACOSX_DEPLOYMENT_TARGET_1040 = 10.4; MACOSX_DEPLOYMENT_TARGET_1050 = 10.5; MACOSX_DEPLOYMENT_TARGET_1060 = 10.6; +MACOSX_DEPLOYMENT_TARGET_1070 = 10.7; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig index ed387aa..42aa3cf 100644 --- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -31,10 +31,12 @@ ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(MAC_OS_X_VERSION_MAJOR)); ENABLE_3D_CANVAS_1050 = ENABLE_3D_CANVAS; ENABLE_3D_CANVAS_1060 = ENABLE_3D_CANVAS; +ENABLE_3D_CANVAS_1070 = ENABLE_3D_CANVAS; ENABLE_3D_RENDERING = $(ENABLE_3D_RENDERING_$(MAC_OS_X_VERSION_MAJOR)); ENABLE_3D_RENDERING_1050 = ENABLE_3D_RENDERING; ENABLE_3D_RENDERING_1060 = ENABLE_3D_RENDERING; +ENABLE_3D_RENDERING_1070 = ENABLE_3D_RENDERING; ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING; ENABLE_DATABASE = ENABLE_DATABASE; diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index 66d574b..fabc009 100644 --- a/JavaScriptCore/Configurations/Version.xcconfig +++ b/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 532; -MINOR_VERSION = 2; +MINOR_VERSION = 4; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); @@ -36,6 +36,7 @@ SYSTEM_VERSION_PREFIX_ = 4; // Some Tiger versions of Xcode don't set MAC_OS_X_V SYSTEM_VERSION_PREFIX_1040 = 4; SYSTEM_VERSION_PREFIX_1050 = 5; SYSTEM_VERSION_PREFIX_1060 = 6; +SYSTEM_VERSION_PREFIX_1070 = 7; // The production build always uses the full version with a system version prefix. BUNDLE_VERSION_Production = $(SYSTEM_VERSION_PREFIX)$(FULL_VERSION); diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index 32e2642..5e50ba7 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -57,6 +57,7 @@ javascriptcore_sources += \ JavaScriptCore/API/JSClassRef.cpp \ JavaScriptCore/API/JSClassRef.h \ JavaScriptCore/API/JSContextRef.cpp \ + JavaScriptCore/API/JSContextRefPrivate.h \ JavaScriptCore/API/JSObjectRef.cpp \ JavaScriptCore/API/JSRetainPtr.h \ JavaScriptCore/API/JSStringRef.cpp \ @@ -133,12 +134,17 @@ javascriptcore_sources += \ JavaScriptCore/icu/unicode/utf_old.h \ JavaScriptCore/icu/unicode/utypes.h \ JavaScriptCore/icu/unicode/uversion.h \ + JavaScriptCore/assembler/ARMAssembler.h \ + JavaScriptCore/assembler/ARMAssembler.cpp \ JavaScriptCore/assembler/X86Assembler.h \ JavaScriptCore/assembler/AbstractMacroAssembler.h \ JavaScriptCore/assembler/AssemblerBuffer.h \ + JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h \ JavaScriptCore/assembler/CodeLocation.h \ JavaScriptCore/assembler/LinkBuffer.h \ JavaScriptCore/assembler/MacroAssembler.h \ + JavaScriptCore/assembler/MacroAssemblerARM.h \ + JavaScriptCore/assembler/MacroAssemblerARM.cpp \ JavaScriptCore/assembler/MacroAssemblerCodeRef.h \ JavaScriptCore/assembler/MacroAssemblerX86.h \ JavaScriptCore/assembler/MacroAssemblerX86_64.h \ @@ -331,12 +337,6 @@ javascriptcore_sources += \ JavaScriptCore/yarr/RegexParser.h \ JavaScriptCore/yarr/RegexPattern.h -# Debug build -if ENABLE_DEBUG -javascriptcore_built_sources += \ - DerivedSources/Grammar.cpp \ - DerivedSources/Grammar.h - javascriptcore_sources += \ JavaScriptCore/interpreter/RegisterFile.cpp \ JavaScriptCore/interpreter/RegisterFile.h \ @@ -390,6 +390,7 @@ javascriptcore_sources += \ JavaScriptCore/runtime/DateConversion.h \ JavaScriptCore/runtime/DateInstance.cpp \ JavaScriptCore/runtime/DateInstance.h \ + JavaScriptCore/runtime/DateInstanceCache.h \ JavaScriptCore/runtime/DatePrototype.cpp \ JavaScriptCore/runtime/DatePrototype.h \ JavaScriptCore/runtime/Error.cpp \ @@ -506,17 +507,10 @@ javascriptcore_sources += \ JavaScriptCore/wtf/dtoa.cpp \ JavaScriptCore/wtf/dtoa.h -else -javascriptcore_built_nosources += \ +javascriptcore_built_sources += \ DerivedSources/Grammar.cpp \ DerivedSources/Grammar.h -javascriptcore_sources += \ - JavaScriptCore/AllInOneFile.cpp \ - JavaScriptCore/parser/ParserArena.cpp \ - JavaScriptCore/parser/ParserArena.h -endif # END ENABLE_DEBUG - DerivedSources/Grammar.h: DerivedSources/Grammar.cpp; DerivedSources/Grammar.cpp: $(srcdir)/JavaScriptCore/parser/Grammar.y diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp index 2934655..12c96b3 100644 --- a/JavaScriptCore/JavaScriptCore.exp +++ b/JavaScriptCore/JavaScriptCore.exp @@ -2,6 +2,7 @@ _JSCheckScriptSyntax _JSClassCreate _JSClassRelease _JSClassRetain +_JSContextGetGlobalContext _JSContextGetGlobalObject _JSContextGetGroup _JSContextGroupCreate @@ -115,6 +116,7 @@ __ZN3JSC12JSGlobalData6createEb __ZN3JSC12JSGlobalDataD1Ev __ZN3JSC12SamplingTool5setupEv __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE +__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE @@ -129,7 +131,6 @@ __ZN3JSC13SamplingFlags4stopEv __ZN3JSC13SamplingFlags5startEv __ZN3JSC13SamplingFlags7s_flagsE __ZN3JSC13StatementNode6setLocEii -__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE __ZN3JSC14JSGlobalObject10globalExecEv __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj __ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj @@ -144,8 +145,8 @@ __ZN3JSC14SamplingThread4stopEv __ZN3JSC14SamplingThread5startEj __ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE __ZN3JSC14TimeoutChecker5resetEv -__ZN3JSC15createTypeErrorEPNS_9ExecStateEPKc __ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE +__ZN3JSC15createTypeErrorEPNS_9ExecStateEPKc __ZN3JSC15toInt32SlowCaseEdRb __ZN3JSC16InternalFunction4infoE __ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE @@ -273,7 +274,6 @@ __ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE __ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE __ZN3JSC8Profiler8profilerEv __ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE -__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE __ZN3JSC9CodeBlockD1Ev __ZN3JSC9CodeBlockD2Ev __ZN3JSC9MarkStack10s_pageSizeE @@ -347,7 +347,6 @@ __ZN3WTF9ByteArray6createEm __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv __ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE __ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE -__ZNK3JSC12DateInstance7getTimeERdRi __ZNK3JSC14JSGlobalObject14isDynamicScopeEv __ZNK3JSC16InternalFunction9classInfoEv __ZNK3JSC16JSVariableObject16isVariableObjectEv diff --git a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp index 88fe484..cfad3cf 100644 --- a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp +++ b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp @@ -121,6 +121,7 @@ # GLib/GTK, even though its name doesn't really indicate. ['exclude', '/(GOwnPtr|glib/.*)\\.(cpp|h)$'], ['exclude', '(Default|Gtk|Mac|None|Qt|Win|Wx)\\.(cpp|mm)$'], + ['exclude', 'wtf/CurrentTime\\.cpp$'], ], 'direct_dependent_settings': { 'include_dirs': [ diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi index 15a0c0f..03c23c3 100644 --- a/JavaScriptCore/JavaScriptCore.gypi +++ b/JavaScriptCore/JavaScriptCore.gypi @@ -1,7 +1,6 @@ { 'variables': { 'javascriptcore_files': [ - 'AllInOneFile.cpp', 'API/APICast.h', 'API/JavaScript.h', 'API/JavaScriptCore.h', @@ -19,6 +18,7 @@ 'API/JSClassRef.h', 'API/JSContextRef.cpp', 'API/JSContextRef.h', + 'API/JSContextRefPrivate.h', 'API/JSObjectRef.cpp', 'API/JSObjectRef.h', 'API/JSProfilerPrivate.cpp', @@ -194,6 +194,7 @@ 'runtime/DateConversion.h', 'runtime/DateInstance.cpp', 'runtime/DateInstance.h', + 'runtime/DateInstanceCache.h', 'runtime/DatePrototype.cpp', 'runtime/DatePrototype.h', 'runtime/Error.cpp', diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri index d69bccb..eb26664 100644 --- a/JavaScriptCore/JavaScriptCore.pri +++ b/JavaScriptCore/JavaScriptCore.pri @@ -39,10 +39,12 @@ win32-* { contains(JAVASCRIPTCORE_JIT,yes) { DEFINES+=ENABLE_JIT=1 DEFINES+=ENABLE_YARR_JIT=1 + DEFINES+=ENABLE_YARR=1 } contains(JAVASCRIPTCORE_JIT,no) { DEFINES+=ENABLE_JIT=0 DEFINES+=ENABLE_YARR_JIT=0 + DEFINES+=ENABLE_YARR=0 } # In debug mode JIT disabled until crash fixed @@ -137,7 +139,8 @@ SOURCES += \ interpreter/RegisterFile.cpp symbian { - SOURCES += runtime/MarkStackSymbian.cpp + SOURCES += jit/ExecutableAllocatorSymbian.cpp \ + runtime/MarkStackSymbian.cpp } else { win32-*|wince* { SOURCES += jit/ExecutableAllocatorWin.cpp \ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make index fbbe23e..806894a 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make @@ -1,7 +1,7 @@ !IF !defined(BUILDSTYLE) BUILDSTYLE=Release !ELSEIF "$(BUILDSTYLE)"=="DEBUG" -BUILDSTYLE=Debug_Internal +BUILDSTYLE=Debug_All !ENDIF install: diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln index 32e7301..69c21bc 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln @@ -20,6 +20,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCoreGenerated", " EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_All|Win32 = Debug_All|Win32
Debug_Internal|Win32 = Debug_Internal|Win32
Debug|Win32 = Debug|Win32
Release_PGOInstrument|Win32 = Release_PGOInstrument|Win32
@@ -27,6 +28,8 @@ Global Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.Build.0 = Debug_All|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -37,6 +40,8 @@ Global {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGOOptimize|Win32.Build.0 = Release_PGOOptimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.ActiveCfg = Release|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.Build.0 = Release|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.Build.0 = Debug_All|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -47,6 +52,8 @@ Global {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release|Win32.ActiveCfg = Release|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release|Win32.Build.0 = Release|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -57,26 +64,30 @@ Global {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.Build.0 = Debug|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.ActiveCfg = Debug|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.Build.0 = Debug|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOInstrument|Win32.ActiveCfg = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOInstrument|Win32.Build.0 = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOOptimize|Win32.ActiveCfg = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.ActiveCfg = Release|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = Release|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_All|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_All|Win32.Build.0 = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.Build.0 = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.Build.0 = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOInstrument|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOInstrument|Win32.Build.0 = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOOptimize|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGOOptimize|Win32.Build.0 = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.ActiveCfg = all|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = all|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index a580b98..01f84f1 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -11,6 +11,7 @@ EXPORTS ??0JSFunction@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V61@ABVArgList@1@@Z@Z ??0Mutex@WTF@@QAE@XZ ??0PrototypeFunction@JSC@@QAE@PAVExecState@1@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V41@ABVArgList@1@@Z@Z + ??0PrototypeFunction@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V61@ABVArgList@1@@Z@Z ??0RefCountedLeakCounter@WTF@@QAE@PBD@Z ??0StringObject@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVUString@1@@Z ??0Structure@JSC@@AAE@VJSValue@1@ABVTypeInfo@1@@Z @@ -77,6 +78,7 @@ EXPORTS ?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ ?createInterruptedExecutionException@JSC@@YA?AVJSValue@1@PAVJSGlobalData@1@@Z ?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ + ?createSingleCharacterString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@E@Z ?createStackOverflowError@JSC@@YA?AVJSValue@1@PAVExecState@1@@Z ?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@@Z ?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z @@ -94,6 +96,7 @@ EXPORTS ?defineSetter@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAVJSObject@2@I@Z ?defineSetter@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAV12@I@Z ?deleteOwnedPtr@WTF@@YAXPAUHBITMAP__@@@Z + ?deleteOwnedPtr@WTF@@YAXPAUHDC__@@@Z ?deleteOwnedPtr@WTF@@YAXPAUHRGN__@@@Z ?deleteProperty@JSCell@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@@Z ?deleteProperty@JSCell@JSC@@UAE_NPAVExecState@2@I@Z diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc index f2b0dd3..ba59bb8 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc @@ -1,7 +1,7 @@ // Microsoft Visual C++ generated resource script. // #include "autoversion.h" -#include "winres.h" +#include "winresrc.h" #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index c86ef7c..bf25a85 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -448,6 +448,67 @@ Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_All|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
@@ -604,6 +665,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\DateInstanceCache.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\DatePrototype.cpp"
>
</File>
@@ -980,11 +1045,11 @@ >
</File>
<File
- RelativePath="..\..\runtime\PropertyDescriptor.h"
+ RelativePath="..\..\runtime\PropertyDescriptor.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\PropertyDescriptor.cpp"
+ RelativePath="..\..\runtime\PropertyDescriptor.h"
>
</File>
<File
@@ -1209,6 +1274,14 @@ DisableSpecificWarnings="4701"
/>
</FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.h"
@@ -1340,6 +1413,10 @@ >
</File>
<File
+ RelativePath="..\..\API\JSContextRefPrivate.h"
+ >
+ </File>
+ <File
RelativePath="..\..\API\JSObjectRef.cpp"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops index ba6bbfd..682e01e 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops @@ -1,30 +1,30 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioPropertySheet - ProjectType="Visual C++" - Version="8.00" - Name="JavaScriptCoreCommon" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\";../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../wrec/;"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\private";../../../icu/include;"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility"" - PreprocessorDefinitions="__STD_C" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="gdi32.lib oleaut32.lib winmm.lib icuin$(LibraryConfigSuffix).lib icuuc$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib WTF$(WebKitConfigSuffix).lib" - OutputFile="$(OutDir)\$(ProjectName)$(WebKitDLLConfigSuffix).dll" - ModuleDefinitionFile="JavaScriptCore$(WebKitDLLConfigSuffix).def" - /> - <Tool - Name="VCPostBuildEventTool" - CommandLine="mkdir 2>NUL "$(WebKitOutputDir)\include\private\JavaScriptCore"

xcopy /y /d "$(ProjectDir)\..\..\wtf\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wtf\unicode\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wtf\unicode\icu\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\parser\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\runtime\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\VM\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\bytecode\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\interpreter\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\assembler\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wrec\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\jit\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\debugger\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\profiler\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\create_hash_table" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\pcre\pcre.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"

mkdir 2>NUL "$(OutDir)\JavaScriptCore.resources"
xcopy /y /d "$(ProjectDir)..\$(ProjectName).resources\*" "$(OutDir)\$(ProjectName).resources"

if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"
" - /> - <Tool - Name="VCPreBuildEventTool" - CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

bash "$(WebKitLibrariesDir)\tools\scripts\auto-version.sh" "$(IntDir)"
" - /> - <Tool - Name="VCPreLinkEventTool" - CommandLine="if not exist "$(WebKitOutputDir)\public\sym" mkdir "$(WebKitOutputDir)\public\sym"" - /> -</VisualStudioPropertySheet> +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreCommon"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\";../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../wrec/;"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\private";../../../icu/include;"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ PreprocessorDefinitions="__STD_C"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="gdi32.lib oleaut32.lib winmm.lib icuin$(LibraryConfigSuffix).lib icuuc$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib WTF$(WebKitConfigSuffix).lib"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitDLLConfigSuffix).dll"
+ ModuleDefinitionFile="JavaScriptCore.def"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2>NUL "$(WebKitOutputDir)\include\private\JavaScriptCore"

xcopy /y /d "$(ProjectDir)\..\..\wtf\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wtf\unicode\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wtf\unicode\icu\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\parser\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\runtime\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\VM\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\bytecode\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\interpreter\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\assembler\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\wrec\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\jit\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\debugger\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\profiler\*.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\create_hash_table" "$(WebKitOutputDir)\include\private\JavaScriptCore"
xcopy /y /d "$(ProjectDir)\..\..\pcre\pcre.h" "$(WebKitOutputDir)\include\private\JavaScriptCore"

mkdir 2>NUL "$(OutDir)\JavaScriptCore.resources"
xcopy /y /d "$(ProjectDir)..\$(ProjectName).resources\*" "$(OutDir)\$(ProjectName).resources"

if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

bash "$(WebKitLibrariesDir)\tools\scripts\auto-version.sh" "$(IntDir)"
"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ CommandLine="if not exist "$(WebKitOutputDir)\public\sym" mkdir "$(WebKitOutputDir)\public\sym""
+ />
+</VisualStudioPropertySheet>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj index 0360c4e..7d5ca69 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj @@ -16,7 +16,7 @@ </ToolFiles>
<Configurations>
<Configuration
- Name="Release|Win32"
+ Name="all|Win32"
OutputDirectory="$(WebKitOutputDir)\lib"
IntermediateDirectory="$(WebKitOutputDir)\obj\$(ProjectName)\$(ConfigurationName)"
ConfigurationType="0"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def deleted file mode 100644 index b91e7b5..0000000 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def +++ /dev/null @@ -1,310 +0,0 @@ -LIBRARY "JavaScriptCore_debug" - -EXPORTS - ??0Collator@WTF@@QAE@PBD@Z - ??0DateInstance@JSC@@QAE@PAVExecState@1@N@Z - ??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z - ??0InternalFunction@JSC@@IAE@PAVJSGlobalData@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVIdentifier@1@@Z - ??0JSArray@JSC@@QAE@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@@Z - ??0JSArray@JSC@@QAE@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVArgList@1@@Z - ??0JSByteArray@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@PAVByteArray@4@PBUClassInfo@1@@Z - ??0JSFunction@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V61@ABVArgList@1@@Z@Z - ??0Mutex@WTF@@QAE@XZ - ??0PrototypeFunction@JSC@@QAE@PAVExecState@1@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V41@ABVArgList@1@@Z@Z - ??0RefCountedLeakCounter@WTF@@QAE@PBD@Z - ??0StringObject@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVUString@1@@Z - ??0Structure@JSC@@AAE@VJSValue@1@ABVTypeInfo@1@@Z - ??0ThreadCondition@WTF@@QAE@XZ - ??0UString@JSC@@QAE@PBD@Z - ??0UString@JSC@@QAE@PB_WH@Z - ??1CString@JSC@@QAE@XZ - ??1ClientData@JSGlobalData@JSC@@UAE@XZ - ??1Collator@WTF@@QAE@XZ - ??1Debugger@JSC@@UAE@XZ - ??1DropAllLocks@JSLock@JSC@@QAE@XZ - ??1JSGlobalData@JSC@@QAE@XZ - ??1JSGlobalObject@JSC@@UAE@XZ - ??1Mutex@WTF@@QAE@XZ - ??1RefCountedLeakCounter@WTF@@QAE@XZ - ??1Structure@JSC@@QAE@XZ - ??1ThreadCondition@WTF@@QAE@XZ - ??2JSCell@JSC@@SAPAXIPAVExecState@1@@Z - ??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z - ??4UString@JSC@@QAEAAV01@PBD@Z - ??8JSC@@YA_NABVUString@0@0@Z - ?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z - ?add@Identifier@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PBD@Z - ?add@PropertyNameArray@JSC@@QAEXPAURep@UString@2@@Z - ?addPropertyTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z - ?addPropertyTransitionToExistingStructure@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z - ?addPropertyWithoutTransition@Structure@JSC@@QAEIABVIdentifier@2@IPAVJSCell@2@@Z - ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PAURep@UString@2@@Z - ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVJSGlobalData@2@PAURep@UString@2@@Z - ?allocate@Heap@JSC@@QAEPAXI@Z - ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z - ?allocateStack@MarkStack@JSC@@CAPAXI@Z - ?append@UString@JSC@@QAEAAV12@ABV12@@Z - ?append@UString@JSC@@QAEAAV12@PBD@Z - ?ascii@UString@JSC@@QBEPADXZ - ?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z - ?broadcast@ThreadCondition@WTF@@QAEXXZ - ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ - ?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z - ?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z - ?changePrototypeTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@VJSValue@2@@Z - ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@PAURep@UString@2@@Z - ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@PAURep@UString@2@@Z - ?checkSyntax@JSC@@YA?AVCompletion@1@PAVExecState@1@ABVSourceCode@1@@Z - ?classInfo@InternalFunction@JSC@@UBEPBUClassInfo@2@XZ - ?classInfo@JSCell@JSC@@UBEPBUClassInfo@2@XZ - ?className@JSObject@JSC@@UBE?AVUString@2@XZ - ?collate@Collator@WTF@@QBE?AW4Result@12@PB_WI0I@Z - ?collect@Heap@JSC@@QAE_NXZ - ?computeHash@Rep@UString@JSC@@SAIPBDH@Z - ?computeHash@Rep@UString@JSC@@SAIPB_WH@Z - ?configurable@PropertyDescriptor@JSC@@QBE_NXZ - ?construct@JSC@@YAPAVJSObject@1@PAVExecState@1@VJSValue@1@W4ConstructType@1@ABTConstructData@1@ABVArgList@1@@Z - ?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z - ?constructEmptyArray@JSC@@YAPAVJSArray@1@PAVExecState@1@@Z - ?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z - ?constructFunction@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@H@Z - ?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z - ?create@ByteArray@WTF@@SA?AV?$PassRefPtr@VByteArray@WTF@@@2@I@Z - ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@_N@Z - ?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVUString@JSC@@@Z - ?create@Rep@UString@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PA_WHV?$PassRefPtr@V?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@@5@@Z - ?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z - ?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ - ?createInterruptedExecutionException@JSC@@YA?AVJSValue@1@PAVJSGlobalData@1@@Z - ?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ - ?createStackOverflowError@JSC@@YA?AVJSValue@1@PAVExecState@1@@Z - ?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@@Z - ?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z - ?createThread@WTF@@YAIP6APAXPAX@Z0@Z - ?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z - ?createTypeError@JSC@@YA?AVJSValue@1@PAVExecState@1@PBD@Z - ?currentThread@WTF@@YAIXZ - ?currentTime@WTF@@YANXZ - ?decrement@RefCountedLeakCounter@WTF@@QAEXXZ - ?defaultAttributes@PropertyDescriptor@JSC@@0IA - ?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z - ?defineGetter@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAVJSObject@2@I@Z - ?defineGetter@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAV12@I@Z - ?defineOwnProperty@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@_N@Z - ?defineSetter@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAVJSObject@2@I@Z - ?defineSetter@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAV12@I@Z - ?deleteOwnedPtr@WTF@@YAXPAUHBITMAP__@@@Z - ?deleteOwnedPtr@WTF@@YAXPAUHRGN__@@@Z - ?deleteProperty@JSCell@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@@Z - ?deleteProperty@JSCell@JSC@@UAE_NPAVExecState@2@I@Z - ?deleteProperty@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@@Z - ?deleteProperty@JSObject@JSC@@UAE_NPAVExecState@2@I@Z - ?deleteProperty@JSVariableObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@@Z - ?deleteProperty@StringObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@@Z - ?deleteTable@HashTable@JSC@@QBEXXZ - ?despecifyDictionaryFunction@Structure@JSC@@QAEXABVIdentifier@2@@Z - ?despecifyFunctionTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@@Z - ?destroy@Heap@JSC@@QAEXXZ - ?destroy@Rep@UString@JSC@@QAEXXZ - ?destroyJSGlobalObjectData@JSGlobalObject@JSC@@CAXPAX@Z - ?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z - ?detachThread@WTF@@YAXI@Z - ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z - ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z - ?enumerable@PropertyDescriptor@JSC@@QBE_NXZ - ?equal@Identifier@JSC@@SA_NPBURep@UString@2@PBD@Z - ?equal@JSC@@YA_NPBURep@UString@1@0@Z - ?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVUString@2@AAV32@@Z - ?evaluate@JSC@@YA?AVCompletion@1@PAVExecState@1@AAVScopeChain@1@ABVSourceCode@1@VJSValue@1@@Z - ?exclude@Profile@JSC@@QAEXPBVProfileNode@2@@Z - ?fastCalloc@WTF@@YAPAXII@Z - ?fastFree@WTF@@YAXPAX@Z - ?fastMalloc@WTF@@YAPAXI@Z - ?fastRealloc@WTF@@YAPAXPAXI@Z - ?fastZeroedMalloc@WTF@@YAPAXI@Z - ?fillGetterPropertySlot@JSObject@JSC@@QAEXAAVPropertySlot@2@PAVJSValue@2@@Z - ?focus@Profile@JSC@@QAEXPBVProfileNode@2@@Z - ?from@UString@JSC@@SA?AV12@H@Z - ?from@UString@JSC@@SA?AV12@I@Z - ?from@UString@JSC@@SA?AV12@N@Z - ?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ - ?get@Structure@JSC@@QAEIPBURep@UString@2@AAIAAPAVJSCell@2@@Z - ?getCallData@JSCell@JSC@@UAE?AW4CallType@2@AATCallData@2@@Z - ?getConstructData@JSCell@JSC@@UAE?AW4ConstructType@2@AATConstructData@2@@Z - ?getJSNumber@JSCell@JSC@@UAE?AVJSValue@2@XZ - ?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ - ?getOwnPropertyDescriptor@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getOwnPropertyDescriptor@JSString@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getOwnPropertyDescriptor@StringObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z - ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@IAAVPropertySlot@2@@Z - ?getOwnPropertySlot@JSObject@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z - ?getOwnPropertySlot@JSString@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z - ?getOwnPropertySlot@JSString@JSC@@EAE_NPAVExecState@2@IAAVPropertySlot@2@@Z - ?getOwnPropertySlot@StringObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z - ?getOwnPropertySlot@StringObject@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z - ?getPrimitiveNumber@JSCell@JSC@@UAE_NPAVExecState@2@AANAAVJSValue@2@@Z - ?getPrimitiveNumber@JSObject@JSC@@UAE_NPAVExecState@2@AANAAVJSValue@2@@Z - ?getPrimitiveNumber@JSString@JSC@@EAE_NPAVExecState@2@AANAAVJSValue@2@@Z - ?getPropertyAttributes@JSObject@JSC@@UBE_NPAVExecState@2@ABVIdentifier@2@AAI@Z - ?getPropertyAttributes@JSVariableObject@JSC@@UBE_NPAVExecState@2@ABVIdentifier@2@AAI@Z - ?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z - ?getString@JSCell@JSC@@QBE?AVUString@2@XZ - ?getString@JSCell@JSC@@QBE_NAAVUString@2@@Z - ?getUInt32@JSCell@JSC@@UBE_NAAI@Z - ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ - ?globalExec@JSGlobalObject@JSC@@UAEPAVExecState@2@XZ - ?globalObjectCount@Heap@JSC@@QAEIXZ - ?hasInstance@JSObject@JSC@@UAE_NPAVExecState@2@VJSValue@2@1@Z - ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@ABVIdentifier@2@@Z - ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z - ?hasTransition@Structure@JSC@@QAE_NPAURep@UString@2@I@Z - ?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z - ?increment@RefCountedLeakCounter@WTF@@QAEXXZ - ?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z - ?initializeMainThread@WTF@@YAXXZ - ?initializeThreading@JSC@@YAXXZ - ?initializeThreading@WTF@@YAXXZ - ?is8Bit@UString@JSC@@QBE_NXZ - ?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ - ?isBusy@Heap@JSC@@QAE_NXZ - ?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ - ?isDynamicScope@JSGlobalObject@JSC@@UBE_NXZ - ?isGetterSetter@JSCell@JSC@@UBE_NXZ - ?isHostFunctionNonInline@JSFunction@JSC@@ABE_NXZ - ?isMainThread@WTF@@YA_NXZ - ?isVariableObject@JSVariableObject@JSC@@UBE_NXZ - ?jsNumberCell@JSC@@YA?AVJSValue@1@PAVExecState@1@N@Z - ?jsOwnedString@JSC@@YAPAVJSString@1@PAVJSGlobalData@1@ABVUString@1@@Z - ?jsRegExpCompile@@YAPAUJSRegExp@@PB_WHW4JSRegExpIgnoreCaseOption@@W4JSRegExpMultilineOption@@PAIPAPBD@Z - ?jsRegExpExecute@@YAHPBUJSRegExp@@PB_WHHPAHH@Z - ?jsRegExpFree@@YAXPAUJSRegExp@@@Z - ?jsString@JSC@@YAPAVJSString@1@PAVJSGlobalData@1@ABVUString@1@@Z - ?lock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z - ?lock@Mutex@WTF@@QAEXXZ - ?lockAtomicallyInitializedStaticMutex@WTF@@YAXXZ - ?lookupGetter@JSObject@JSC@@UAE?AVJSValue@2@PAVExecState@2@ABVIdentifier@2@@Z - ?lookupSetter@JSObject@JSC@@UAE?AVJSValue@2@PAVExecState@2@ABVIdentifier@2@@Z - ?markChildren@JSGlobalObject@JSC@@UAEXAAVMarkStack@2@@Z - ?markChildren@JSObject@JSC@@UAEXAAVMarkStack@2@@Z - ?markChildren@JSWrapperObject@JSC@@EAEXAAVMarkStack@2@@Z - ?materializePropertyMap@Structure@JSC@@AAEXXZ - ?name@InternalFunction@JSC@@QAEABVUString@2@PAVJSGlobalData@2@@Z - ?nonInlineNaN@JSC@@YANXZ - ?objectCount@Heap@JSC@@QAEIXZ - ?objectProtoFuncToString@JSC@@YI?AVJSValue@1@PAVExecState@1@PAVJSObject@1@V21@ABVArgList@1@@Z - ?parse@Parser@JSC@@AAEXPAVJSGlobalData@2@PAHPAVUString@2@@Z - ?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z - ?primaryHeapBegin@Heap@JSC@@QAE?AV?$CollectorHeapIterator@$0A@@2@XZ - ?primaryHeapEnd@Heap@JSC@@QAE?AV?$CollectorHeapIterator@$0A@@2@XZ - ?profiler@Profiler@JSC@@SAPAV12@XZ - ?protect@Heap@JSC@@QAEXVJSValue@2@@Z - ?protectedGlobalObjectCount@Heap@JSC@@QAEIXZ - ?protectedObjectCount@Heap@JSC@@QAEIXZ - ?protectedObjectTypeCounts@Heap@JSC@@QAEPAV?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@XZ - ?put@JSCell@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z - ?put@JSCell@JSC@@UAEXPAVExecState@2@IVJSValue@2@@Z - ?put@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z - ?put@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z - ?put@JSObject@JSC@@UAEXPAVExecState@2@IVJSValue@2@@Z - ?put@StringObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@AAVPutPropertySlot@2@@Z - ?putDirectFunction@JSObject@JSC@@QAEXPAVExecState@2@PAVInternalFunction@2@I@Z - ?putWithAttributes@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@I@Z - ?putWithAttributes@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@I@Z - ?putWithAttributes@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@VJSValue@2@I_NAAVPutPropertySlot@2@@Z - ?putWithAttributes@JSObject@JSC@@UAEXPAVExecState@2@IVJSValue@2@I@Z - ?randomNumber@WTF@@YANXZ - ?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z - ?recordExtraCost@Heap@JSC@@AAEXI@Z - ?releaseStack@MarkStack@JSC@@CAXPAXI@Z - ?reset@ParserArena@JSC@@QAEXXZ - ?reset@TimeoutChecker@JSC@@QAEXXZ - ?restoreAll@Profile@JSC@@QAEXXZ - ?retrieveCaller@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVInternalFunction@2@@Z - ?retrieveLastCaller@Interpreter@JSC@@QBEXPAVExecState@2@AAH1AAVUString@2@AAVJSValue@2@@Z - ?setAccessorDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@0I@Z - ?setConfigurable@PropertyDescriptor@JSC@@QAEX_N@Z - ?setDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@I@Z - ?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z - ?setEnumerable@PropertyDescriptor@JSC@@QAEX_N@Z - ?setGetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z - ?setLength@JSArray@JSC@@QAEXI@Z - ?setLoc@StatementNode@JSC@@QAEXHH@Z - ?setMainThreadCallbacksPaused@WTF@@YAX_N@Z - ?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z - ?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z - ?setUndefined@PropertyDescriptor@JSC@@QAEXXZ - ?setUpStaticFunctionSlot@JSC@@YAXPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@ABVIdentifier@1@AAVPropertySlot@1@@Z - ?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z - ?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ - ?sharedBuffer@Rep@UString@JSC@@QAEPAV?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@XZ - ?signal@ThreadCondition@WTF@@QAEXXZ - ?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z - ?startIgnoringLeaks@Structure@JSC@@SAXXZ - ?startProfiling@Profiler@JSC@@QAEXPAVExecState@2@ABVUString@2@@Z - ?startSampling@JSGlobalData@JSC@@QAEXXZ - ?stopIgnoringLeaks@Structure@JSC@@SAXXZ - ?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVUString@2@@Z - ?stopSampling@JSGlobalData@JSC@@QAEXXZ - ?strtod@WTF@@YANPBDPAPAD@Z - ?substr@UString@JSC@@QBE?AV12@HH@Z - ?symbolTableGet@JSVariableObject@JSC@@IAE_NABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?synthesizePrototype@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z - ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ - ?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@@Z - ?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@ABVUString@1@@Z - ?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@PBD@Z - ?timedWait@ThreadCondition@WTF@@QAE_NAAVMutex@2@N@Z - ?tlsKeyCount@WTF@@YAAAJXZ - ?tlsKeys@WTF@@YAPAKXZ - ?toBoolean@JSCell@JSC@@UBE_NPAVExecState@2@@Z - ?toBoolean@JSObject@JSC@@UBE_NPAVExecState@2@@Z - ?toBoolean@JSString@JSC@@EBE_NPAVExecState@2@@Z - ?toInt32SlowCase@JSC@@YAHNAA_N@Z - ?toNumber@JSCell@JSC@@UBENPAVExecState@2@@Z - ?toNumber@JSObject@JSC@@UBENPAVExecState@2@@Z - ?toNumber@JSString@JSC@@EBENPAVExecState@2@@Z - ?toObject@JSCell@JSC@@UBEPAVJSObject@2@PAVExecState@2@@Z - ?toObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@@Z - ?toObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z - ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z - ?toPrimitive@JSCell@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z - ?toPrimitive@JSString@JSC@@EBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z - ?toStrictUInt32@UString@JSC@@QBEIPA_N@Z - ?toString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z - ?toString@JSObject@JSC@@UBE?AVUString@2@PAVExecState@2@@Z - ?toString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z - ?toThisJSString@JSCell@JSC@@UAEPAVJSString@2@PAVExecState@2@@Z - ?toThisJSString@JSString@JSC@@EAEPAV12@PAVExecState@2@@Z - ?toThisObject@JSCell@JSC@@UBEPAVJSObject@2@PAVExecState@2@@Z - ?toThisObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@@Z - ?toThisObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z - ?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z - ?toThisString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z - ?toThisString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z - ?toUInt32@UString@JSC@@QBEIPA_N@Z - ?toUInt32@UString@JSC@@QBEIPA_N_N@Z - ?toUInt32SlowCase@JSC@@YAINAA_N@Z - ?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z - ?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z - ?tryLock@Mutex@WTF@@QAE_NXZ - ?type@DebuggerCallFrame@JSC@@QBE?AW4Type@12@XZ - ?unlock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z - ?unlock@Mutex@WTF@@QAEXXZ - ?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ - ?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z - ?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ - ?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z - ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z - ?writable@PropertyDescriptor@JSC@@QBE_NXZ - WTFLog - WTFLogVerbose - WTFReportArgumentAssertionFailure - WTFReportAssertionFailure - WTFReportAssertionFailureWithMessage - WTFReportError diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln index fe3a7ba..142e5bc 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln @@ -20,6 +20,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcproj", "{C EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_All|Win32 = Debug_All|Win32
Debug_Internal|Win32 = Debug_Internal|Win32
Debug|Win32 = Debug|Win32
Release_PGOInstrument|Win32 = Release_PGOInstrument|Win32
@@ -27,6 +28,8 @@ Global Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.Build.0 = Debug_All|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -37,6 +40,8 @@ Global {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGOOptimize|Win32.Build.0 = Release_PGOOptimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.ActiveCfg = Release|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release|Win32.Build.0 = Release|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -47,16 +52,20 @@ Global {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.Build.0 = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = Release|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_Internal|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOInstrument|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGOOptimize|Win32.Build.0 = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = all|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = all|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.Build.0 = Debug_All|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.ActiveCfg = Debug|Win32
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj index 6ed89e5..67c004c 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj @@ -172,6 +172,58 @@ Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_All|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\WTFCommon.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj index dd18269..76c1550 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj @@ -260,6 +260,67 @@ Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_All|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\jscCommon.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj index fbc4672..9581e54 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj @@ -322,6 +322,67 @@ Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_All|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
@@ -369,6 +430,14 @@ CompileAs="2"
/>
</FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath="..\..\API\tests\testapi.js"
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index f108b77..48cf396 100644 --- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -44,11 +44,30 @@ 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; }; + 140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; }; + 140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; }; 140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; }; 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; }; 141211340A48795800480255 /* minidom.c in Sources */ = {isa = PBXBuildFile; fileRef = 141211020A48780900480255 /* minidom.c */; }; 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1421359A0A677F4F00A8195E /* JSBase.cpp */; }; + 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8580255597D01FF60F7 /* Debugger.cpp */; }; + 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA62DFE0E2826230004F30D /* CallData.cpp */; }; + 1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA62DFF0E2826310004F30D /* ConstructData.cpp */; }; + 1428083A107EC0750013E7B2 /* RegisterFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D85B0ED218E900B89619 /* RegisterFile.cpp */; }; + 14280841107EC0930013E7B2 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A87D0255597D01FF60F7 /* RegExp.cpp */; }; + 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */; }; + 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A87B0255597D01FF60F7 /* RegExpObject.cpp */; }; + 14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */; }; + 14280850107EC0D70013E7B2 /* Operations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8770255597D01FF60F7 /* Operations.cpp */; }; + 14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B80E184545000F9297 /* GetterSetter.cpp */; }; + 1428085D107EC0F80013E7B2 /* JSNumberCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B90E184580000F9297 /* JSNumberCell.cpp */; }; + 14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952320E15EB5600A898AB /* BooleanConstructor.cpp */; }; + 14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8500255597D01FF60F7 /* BooleanObject.cpp */; }; + 14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */; }; + 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */; }; + 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA4C99092AF9E20093D800 /* JSLock.cpp */; }; 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D77B0ED20D7300B89619 /* Interpreter.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D7D30ED2128200B89619 /* Interpreter.cpp */; settings = {COMPILER_FLAGS = "-fno-var-tracking"; }; }; 1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */; }; @@ -81,12 +100,64 @@ 1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440F8900A508B100005F061 /* JSCallbackFunction.cpp */; }; 1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440F8AD0A508D200005F061 /* JSCallbackConstructor.cpp */; }; 1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440FCE20A51E46B0005F061 /* JSClassRef.cpp */; }; + 14469DD7107EC79E00650446 /* dtoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651F6412039D5B5F0078395C /* dtoa.cpp */; }; + 14469DDE107EC7E700650446 /* Lookup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8680255597D01FF60F7 /* Lookup.cpp */; }; + 14469DDF107EC7E700650446 /* MathObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A86A0255597D01FF60F7 /* MathObject.cpp */; }; + 14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */; }; + 14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E90A0E1839DB000F9297 /* NativeErrorPrototype.cpp */; }; + 14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */; }; + 14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8700255597D01FF60F7 /* NumberObject.cpp */; }; + 14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C40E16D4E900A06E92 /* NumberPrototype.cpp */; }; + 14469DE5107EC7E700650446 /* ObjectConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C60E16D4E900A06E92 /* ObjectConstructor.cpp */; }; + 14469DE6107EC7E700650446 /* ObjectPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */; }; + 14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */; }; + 14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* PropertySlot.cpp */; }; + 14469DE9107EC7E700650446 /* PrototypeFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DF10E1F53740016B6C9 /* PrototypeFunction.cpp */; }; + 14469DEA107EC7E700650446 /* ScopeChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9374D3A8038D9D74008635CE /* ScopeChain.cpp */; }; + 14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */; }; + 14469DEC107EC7E700650446 /* StringObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C20E16EE3300B34460 /* StringObject.cpp */; }; + 14469DED107EC7E700650446 /* StringPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */; }; + 14469DEE107EC7E700650446 /* UString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8850255597D01FF60F7 /* UString.cpp */; }; 146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146AAB370B66A94400E55F16 /* JSStringRefCF.cpp */; }; 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; }; 147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF605110E203EF800B9A64D /* ArgList.cpp */; }; + 147F39BE107EC37600427A48 /* Arguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DE50E1F51C50016B6C9 /* Arguments.cpp */; }; + 147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; }; + 147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; }; + 147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */; }; + 147F39C2107EC37600427A48 /* Completion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A09220ED1E09C00F1F681 /* Completion.cpp */; }; + 147F39C3107EC37600427A48 /* DateConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD203450E17135E002C7E82 /* DateConstructor.cpp */; }; + 147F39C4107EC37600427A48 /* DateConversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D21202280AD4310C00ED79B6 /* DateConversion.cpp */; }; + 147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC1166000E1997B1008066DD /* DateInstance.cpp */; }; + 147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD203470E17135E002C7E82 /* DatePrototype.cpp */; }; + 147F39C7107EC37600427A48 /* Error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC337BEA0E1B00CB0076918A /* Error.cpp */; }; + 147F39C8107EC37600427A48 /* ErrorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */; }; + 147F39C9107EC37600427A48 /* ErrorInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E98A0E183E38000F9297 /* ErrorInstance.cpp */; }; + 147F39CA107EC37600427A48 /* ErrorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */; }; + 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */; }; + 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */; }; + 147F39CD107EC37600427A48 /* GlobalEvalFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */; }; + 147F39CE107EC37600427A48 /* Identifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933A349D038AE80F008635CE /* Identifier.cpp */; }; + 147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */; }; + 147F39D0107EC37600427A48 /* JSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */; }; + 147F39D1107EC37600427A48 /* JSCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */; }; + 147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */; }; + 147F39D3107EC37600427A48 /* JSImmediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14760863099C633800437128 /* JSImmediate.cpp */; }; + 147F39D4107EC37600427A48 /* JSObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A3980E16E14800AF21C8 /* JSObject.cpp */; }; + 147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; }; + 147F39D6107EC37600427A48 /* JSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSValue.cpp */; }; + 147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */; }; 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; }; 1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; }; + 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 148F21A3107EC5310042EC2C /* Grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB3F4809D11B2400F49DEB /* Grammar.cpp */; }; + 148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */; }; + 148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8650255597D01FF60F7 /* Lexer.cpp */; }; + 148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A86D0255597D01FF60F7 /* Nodes.cpp */; }; + 148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */; }; 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */; }; + 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A1563010966365006FA260 /* DateInstanceCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */; }; 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */; }; 14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -96,7 +167,11 @@ 14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; }; 14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; }; 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6581A0F4E36F4000150FD /* JITStubs.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */; }; 14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */; settings = {ATTRIBUTES = (); }; }; + 14F8BA3E107EC886009892DC /* FastMalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */; }; + 14F8BA43107EC88C009892DC /* TCSystemAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */; }; + 14F8BA4F107EC899009892DC /* Collector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8520255597D01FF60F7 /* Collector.cpp */; }; 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; }; 180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */; }; 1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; }; @@ -112,7 +187,6 @@ 5D6A566B0F05995500266145 /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D6A566A0F05995500266145 /* Threading.cpp */; }; 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; }; 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 659126BD0BDD1728001921FB /* AllInOneFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 659126BC0BDD1728001921FB /* AllInOneFile.cpp */; }; 65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; }; 65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; settings = {COMPILER_FLAGS = "-Wno-missing-format-attribute"; }; }; 7E2ADD8E0E79AAD500D50C51 /* CharacterClassConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E2ADD8D0E79AAD500D50C51 /* CharacterClassConstructor.h */; }; @@ -356,8 +430,8 @@ BC18C5260E16FCA700B34460 /* StringPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5250E16FCA700B34460 /* StringPrototype.lut.h */; }; BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5290E16FCC200B34460 /* MathObject.lut.h */; }; BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */; }; - BC18C52E0E16FCE100B34460 /* lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* lexer.lut.h */; }; - BC18C5300E16FCEB00B34460 /* grammar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52F0E16FCEB00B34460 /* grammar.h */; }; + BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* Lexer.lut.h */; }; + BC18C5300E16FCEB00B34460 /* Grammar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52F0E16FCEB00B34460 /* Grammar.h */; }; BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; }; BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */; }; BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -539,8 +613,10 @@ 1483B589099BC1950016E4F0 /* JSImmediate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSImmediate.h; sourceTree = "<group>"; }; 148A1626095D16BB00666D0D /* ListRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListRefPtr.h; sourceTree = "<group>"; }; 148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefPtrHashMap.h; sourceTree = "<group>"; }; + 148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSContextRefPrivate.h; sourceTree = "<group>"; }; 149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerCallFrame.cpp; sourceTree = "<group>"; }; 149B24FF0D8AF6D1009CB8C7 /* Register.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Register.h; sourceTree = "<group>"; }; + 14A1563010966365006FA260 /* DateInstanceCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateInstanceCache.h; sourceTree = "<group>"; }; 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubs.cpp; sourceTree = "<group>"; }; 14A396A60CD2933100B5B4FF /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; }; 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeoutChecker.cpp; sourceTree = "<group>"; }; @@ -608,7 +684,6 @@ 657EB7450B708F540063461B /* ListHashSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListHashSet.h; sourceTree = "<group>"; }; 657EEBBF094E445E008C9C7B /* HashCountedSet.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashCountedSet.h; sourceTree = "<group>"; tabWidth = 8; }; 6580F795094070560082C219 /* PassRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PassRefPtr.h; sourceTree = "<group>"; tabWidth = 8; }; - 659126BC0BDD1728001921FB /* AllInOneFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AllInOneFile.cpp; sourceTree = "<group>"; }; 6592C316098B7DE10003D4F6 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; }; 6592C317098B7DE10003D4F6 /* VectorTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VectorTraits.h; sourceTree = "<group>"; }; 65B174BE09D1000200820339 /* chartables.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 30; path = chartables.c; sourceTree = "<group>"; }; @@ -633,7 +708,7 @@ 65EA4C9A092AF9E20093D800 /* JSLock.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JSLock.h; sourceTree = "<group>"; tabWidth = 8; }; 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; }; 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; }; - 65FB3F4809D11B2400F49DEB /* grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = grammar.cpp; sourceTree = "<group>"; }; + 65FB3F4809D11B2400F49DEB /* Grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Grammar.cpp; sourceTree = "<group>"; }; 704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; }; 7E2ADD8D0E79AAD500D50C51 /* CharacterClassConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterClassConstructor.h; sourceTree = "<group>"; }; 7E2ADD8F0E79AC1100D50C51 /* CharacterClassConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharacterClassConstructor.cpp; sourceTree = "<group>"; }; @@ -804,8 +879,8 @@ BC18C5250E16FCA700B34460 /* StringPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringPrototype.lut.h; sourceTree = "<group>"; }; BC18C5290E16FCC200B34460 /* MathObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathObject.lut.h; sourceTree = "<group>"; }; BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObject.lut.h; sourceTree = "<group>"; }; - BC18C52D0E16FCE100B34460 /* lexer.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lexer.lut.h; sourceTree = "<group>"; }; - BC18C52F0E16FCEB00B34460 /* grammar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grammar.h; sourceTree = "<group>"; }; + BC18C52D0E16FCE100B34460 /* Lexer.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.lut.h; sourceTree = "<group>"; }; + BC18C52F0E16FCEB00B34460 /* Grammar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Grammar.h; sourceTree = "<group>"; }; BC22A3980E16E14800AF21C8 /* JSObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObject.cpp; sourceTree = "<group>"; }; BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; }; BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVariableObject.cpp; sourceTree = "<group>"; }; @@ -1001,7 +1076,6 @@ F692A8540255597D01FF60F7 /* create_hash_table */, 14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */, F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */, - 659126BC0BDD1728001921FB /* AllInOneFile.cpp */, 45E12D8806A49B0F00E9DF84 /* jsc.cpp */, F68EBB8C0255D4C601FF60F7 /* config.h */, 1432EBD70A34CAD400717B9F /* API */, @@ -1115,6 +1189,7 @@ 1440FCE10A51E46B0005F061 /* JSClassRef.h */, 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */, 14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */, + 148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */, 1482B7E20A43076000517CFC /* JSObjectRef.cpp */, 1482B7E10A43076000517CFC /* JSObjectRef.h */, 95988BA90E477BEC00D28D4D /* JSProfilerPrivate.cpp */, @@ -1186,10 +1261,10 @@ BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */, 65B174BE09D1000200820339 /* chartables.c */, BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */, - 65FB3F4809D11B2400F49DEB /* grammar.cpp */, - BC18C52F0E16FCEB00B34460 /* grammar.h */, + 65FB3F4809D11B2400F49DEB /* Grammar.cpp */, + BC18C52F0E16FCEB00B34460 /* Grammar.h */, BC87CDB810712ACA000614CF /* JSONObject.lut.h */, - BC18C52D0E16FCE100B34460 /* lexer.lut.h */, + BC18C52D0E16FCE100B34460 /* Lexer.lut.h */, BC18C5290E16FCC200B34460 /* MathObject.lut.h */, BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */, BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */, @@ -1343,7 +1418,6 @@ 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = { isa = PBXGroup; children = ( - A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */, BCF605110E203EF800B9A64D /* ArgList.cpp */, BCF605120E203EF800B9A64D /* ArgList.h */, BC257DE50E1F51C50016B6C9 /* Arguments.cpp */, @@ -1377,6 +1451,7 @@ D21202290AD4310C00ED79B6 /* DateConversion.h */, BC1166000E1997B1008066DD /* DateInstance.cpp */, BC1166010E1997B1008066DD /* DateInstance.h */, + 14A1563010966365006FA260 /* DateInstanceCache.h */, BCD203470E17135E002C7E82 /* DatePrototype.cpp */, BCD203480E17135E002C7E82 /* DatePrototype.h */, BC337BEA0E1B00CB0076918A /* Error.cpp */, @@ -1440,6 +1515,7 @@ BC02E9B60E1842FA000F9297 /* JSString.cpp */, F692A8620255597D01FF60F7 /* JSString.h */, 14ABB454099C2A0F00E2A24F /* JSType.h */, + 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */, F692A8870255597D01FF60F7 /* JSValue.cpp */, 14ABB36E099C076400E2A24F /* JSValue.h */, BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */, @@ -1450,6 +1526,9 @@ A7E2EA690FB460CF00601F06 /* LiteralParser.h */, F692A8680255597D01FF60F7 /* Lookup.cpp */, F692A8690255597D01FF60F7 /* Lookup.h */, + A74B3498102A5F8E0032AB98 /* MarkStack.cpp */, + A779558F101A74D500114E55 /* MarkStack.h */, + A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */, F692A86A0255597D01FF60F7 /* MathObject.cpp */, F692A86B0255597D01FF60F7 /* MathObject.h */, BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */, @@ -1470,6 +1549,8 @@ BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */, F692A8770255597D01FF60F7 /* Operations.cpp */, F692A8780255597D01FF60F7 /* Operations.h */, + A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */, + A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */, BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */, 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */, 65400C100A69BAF200509887 /* PropertyNameArray.h */, @@ -1510,13 +1591,8 @@ 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */, 5D53726D0E1C546B0021E549 /* Tracing.d */, 5D53726E0E1C54880021E549 /* Tracing.h */, - 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */, F692A8850255597D01FF60F7 /* UString.cpp */, F692A8860255597D01FF60F7 /* UString.h */, - A779558F101A74D500114E55 /* MarkStack.h */, - A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */, - A74B3498102A5F8E0032AB98 /* MarkStack.cpp */, - A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */, ); path = runtime; sourceTree = "<group>"; @@ -1734,7 +1810,7 @@ BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */, BC18C4060E16F5CD00B34460 /* GetPtr.h in Headers */, BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */, - BC18C5300E16FCEB00B34460 /* grammar.h in Headers */, + BC18C5300E16FCEB00B34460 /* Grammar.h in Headers */, BC18C4080E16F5CD00B34460 /* HashCountedSet.h in Headers */, BC18C4090E16F5CD00B34460 /* HashFunctions.h in Headers */, BC18C40A0E16F5CD00B34460 /* HashIterators.h in Headers */, @@ -1792,7 +1868,7 @@ 969A072A0ED1CE6900F1F681 /* Label.h in Headers */, 960097A60EBABB58007A7297 /* LabelScope.h in Headers */, BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */, - BC18C52E0E16FCE100B34460 /* lexer.lut.h in Headers */, + BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */, 86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */, BC18C4340E16F5CD00B34460 /* ListHashSet.h in Headers */, BC18C4350E16F5CD00B34460 /* ListRefPtr.h in Headers */, @@ -1924,6 +2000,8 @@ 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */, A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */, + 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */, + 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2210,26 +2288,57 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 659126BD0BDD1728001921FB /* AllInOneFile.cpp in Sources */, + 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */, + 147F39BE107EC37600427A48 /* Arguments.cpp in Sources */, 86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */, + 147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */, + 147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */, 65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */, + 14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */, + 14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */, + 14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */, A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */, + 148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */, + 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */, 1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */, 1429D9C40ED23C3900B89619 /* CharacterClass.cpp in Sources */, 7E2ADD900E79AC1100D50C51 /* CharacterClassConstructor.cpp in Sources */, 969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */, E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */, E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */, + 14F8BA4F107EC899009892DC /* Collector.cpp in Sources */, + 147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */, + 147F39C2107EC37600427A48 /* Completion.cpp in Sources */, + 1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */, 180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */, + 147F39C3107EC37600427A48 /* DateConstructor.cpp in Sources */, + 147F39C4107EC37600427A48 /* DateConversion.cpp in Sources */, + 147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */, 41359CF60FDD89CB00206180 /* DateMath.cpp in Sources */, + 147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */, + 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */, BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */, 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */, + 14469DD7107EC79E00650446 /* dtoa.cpp in Sources */, + 147F39C7107EC37600427A48 /* Error.cpp in Sources */, + 147F39C8107EC37600427A48 /* ErrorConstructor.cpp in Sources */, + 147F39C9107EC37600427A48 /* ErrorInstance.cpp in Sources */, + 147F39CA107EC37600427A48 /* ErrorPrototype.cpp in Sources */, 1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */, + 86CA032E1038E8440028A609 /* Executable.cpp in Sources */, A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */, 86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */, A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */, + 14F8BA3E107EC886009892DC /* FastMalloc.cpp in Sources */, + 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */, + 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */, + 14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */, + 147F39CD107EC37600427A48 /* GlobalEvalFunction.cpp in Sources */, + 148F21A3107EC5310042EC2C /* Grammar.cpp in Sources */, 65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */, + 147F39CE107EC37600427A48 /* Identifier.cpp in Sources */, E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */, + 147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */, 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */, 1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */, 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */, @@ -2238,28 +2347,58 @@ 86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */, 14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */, 140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */, + 140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */, + 147F39D0107EC37600427A48 /* JSArray.cpp in Sources */, 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */, A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */, 1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */, 1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */, 14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */, + 147F39D1107EC37600427A48 /* JSCell.cpp in Sources */, 1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */, 14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */, + 140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */, E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */, + 147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */, + 14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */, + 147F39D3107EC37600427A48 /* JSImmediate.cpp in Sources */, + 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */, A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */, + 1428085D107EC0F80013E7B2 /* JSNumberCell.cpp in Sources */, + 147F39D4107EC37600427A48 /* JSObject.cpp in Sources */, 1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */, A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */, 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */, A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */, + 140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */, + 147F39D5107EC37600427A48 /* JSString.cpp in Sources */, 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */, 146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */, + 147F39D6107EC37600427A48 /* JSValue.cpp in Sources */, 14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */, + 147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */, + 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */, BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */, + 148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */, A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */, + 14469DDE107EC7E700650446 /* Lookup.cpp in Sources */, 06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */, 06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */, + A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */, + A7C530E4102A3813005BC741 /* MarkStackPosix.cpp in Sources */, + 14469DDF107EC7E700650446 /* MathObject.cpp in Sources */, + 14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */, + 14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */, + 148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */, + 14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */, + 14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */, + 14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */, + 14469DE5107EC7E700650446 /* ObjectConstructor.cpp in Sources */, + 14469DE6107EC7E700650446 /* ObjectPrototype.cpp in Sources */, E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */, 969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */, + 14280850107EC0D70013E7B2 /* Operations.cpp in Sources */, + 148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */, 93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */, 930754C108B0F68000AB3056 /* pcre_compile.cpp in Sources */, 930754EB08B0F78500AB3056 /* pcre_exec.cpp in Sources */, @@ -2271,29 +2410,40 @@ 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */, 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */, 1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */, + A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */, + 14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */, + 14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */, + 14469DE9107EC7E700650446 /* PrototypeFunction.cpp in Sources */, 088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */, 905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */, 86EAC4950F93E8D1008EC948 /* RegexCompiler.cpp in Sources */, 86EAC4970F93E8D1008EC948 /* RegexInterpreter.cpp in Sources */, 86EAC4990F93E8D1008EC948 /* RegexJIT.cpp in Sources */, + 14280841107EC0930013E7B2 /* RegExp.cpp in Sources */, + 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */, + 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */, + 14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */, + 1428083A107EC0750013E7B2 /* RegisterFile.cpp in Sources */, 1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */, + 14469DEA107EC7E700650446 /* ScopeChain.cpp in Sources */, 9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */, + 14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */, + 14469DEC107EC7E700650446 /* StringObject.cpp in Sources */, + 14469DED107EC7E700650446 /* StringPrototype.cpp in Sources */, BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */, 7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */, BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */, + 14F8BA43107EC88C009892DC /* TCSystemAlloc.cpp in Sources */, 5D6A566B0F05995500266145 /* Threading.cpp in Sources */, E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */, 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */, 0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */, + 14469DEE107EC7E700650446 /* UString.cpp in Sources */, E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */, 869083150E6518D7000D36ED /* WREC.cpp in Sources */, 1429DA820ED2482900B89619 /* WRECFunctors.cpp in Sources */, 1429DAE10ED2645B00B89619 /* WRECGenerator.cpp in Sources */, 1429DAC00ED263E700B89619 /* WRECParser.cpp in Sources */, - A7C530E4102A3813005BC741 /* MarkStackPosix.cpp in Sources */, - A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */, - 86CA032E1038E8440028A609 /* Executable.cpp in Sources */, - A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h index 078de44..02ce2e9 100644 --- a/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/JavaScriptCore/assembler/ARMv7Assembler.h @@ -407,6 +407,11 @@ register writeback class ARMv7Assembler { public: + ~ARMv7Assembler() + { + ASSERT(m_jumpsToLink.isEmpty()); + } + typedef ARMRegisters::RegisterID RegisterID; typedef ARMRegisters::FPRegisterID FPRegisterID; @@ -477,6 +482,17 @@ public: private: + struct LinkRecord { + LinkRecord(intptr_t from, intptr_t to) + : from(from) + , to(to) + { + } + + intptr_t from; + intptr_t to; + }; + // ARMv7, Appx-A.6.3 bool BadReg(RegisterID reg) { @@ -574,6 +590,7 @@ private: OP_SUB_SP_imm_T1 = 0xB080, OP_BKPT = 0xBE00, OP_IT = 0xBF00, + OP_NOP_T1 = 0xBF00, } OpcodeID; typedef enum { @@ -608,6 +625,7 @@ private: OP_MOV_imm_T3 = 0xF240, OP_SUB_imm_T4 = 0xF2A0, OP_MOVT = 0xF2C0, + OP_NOP_T2a = 0xF3AF, OP_LDRH_reg_T2 = 0xF830, OP_LDRH_imm_T3 = 0xF830, OP_STR_imm_T4 = 0xF840, @@ -626,6 +644,7 @@ private: typedef enum { OP_B_T4b = 0x9000, + OP_NOP_T2b = 0x8000, } OpcodeID2; struct FourFours { @@ -1481,6 +1500,15 @@ public: void* executableCopy(ExecutablePool* allocator) { void* copy = m_formatter.executableCopy(allocator); + + unsigned jumpCount = m_jumpsToLink.size(); + for (unsigned i = 0; i < jumpCount; ++i) { + uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].from); + uint16_t* target = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].to); + linkJumpAbsolute(location, target); + } + m_jumpsToLink.clear(); + ASSERT(copy); return copy; } @@ -1503,11 +1531,7 @@ public: { ASSERT(to.m_offset != -1); ASSERT(from.m_offset != -1); - - uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(m_formatter.data()) + from.m_offset); - intptr_t relative = to.m_offset - from.m_offset; - - linkWithOffset(location, relative); + m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset)); } static void linkJump(void* code, JmpSrc from, void* to) @@ -1515,9 +1539,7 @@ public: ASSERT(from.m_offset != -1); uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset); - intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(location); - - linkWithOffset(location, relative); + linkJumpAbsolute(location, to); } // bah, this mathod should really be static, since it is used by the LinkBuffer. @@ -1541,10 +1563,9 @@ public: ASSERT(!(reinterpret_cast<intptr_t>(from) & 1)); ASSERT(!(reinterpret_cast<intptr_t>(to) & 1)); - intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from); - linkWithOffset(reinterpret_cast<uint16_t*>(from), relative); + linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to); - ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 2, 2 * sizeof(uint16_t)); + ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t)); } static void relinkCall(void* from, void* to) @@ -1613,14 +1634,14 @@ private: static void setInt32(void* code, uint32_t value) { uint16_t* location = reinterpret_cast<uint16_t*>(code); + ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2)); - uint16_t lo16 = value; - uint16_t hi16 = value >> 16; - - spliceHi5(location - 4, lo16); - spliceLo11(location - 3, lo16); - spliceHi5(location - 2, hi16); - spliceLo11(location - 1, hi16); + ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value)); + ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value >> 16)); + location[-4] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); + location[-3] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-3] >> 8) & 0xf, lo16); + location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); + location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16); ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t)); } @@ -1630,41 +1651,89 @@ private: setInt32(code, reinterpret_cast<uint32_t>(value)); } - // Linking & patching: - // This method assumes that the JmpSrc being linked is a T4 b instruction. - static void linkWithOffset(uint16_t* instruction, intptr_t relative) - { - // Currently branches > 16m = mostly deathy. - if (((relative << 7) >> 7) != relative) { - // FIXME: This CRASH means we cannot turn the JIT on by default on arm-v7. - fprintf(stderr, "Error: Cannot link T4b.\n"); - CRASH(); - } - - // ARM encoding for the top two bits below the sign bit is 'peculiar'. - if (relative >= 0) - relative ^= 0xC00000; + static bool isB(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xf800) == OP_B_T4a) && ((instruction[1] & 0xd000) == OP_B_T4b); + } + + static bool isBX(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return (instruction[0] & 0xff87) == OP_BX; + } - // All branch offsets should be an even distance. - ASSERT(!(relative & 1)); + static bool isMOV_imm_T3(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xFBF0) == OP_MOV_imm_T3) && ((instruction[1] & 0x8000) == 0); + } - int word1 = ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); - int word2 = ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); + static bool isMOVT(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return ((instruction[0] & 0xFBF0) == OP_MOVT) && ((instruction[1] & 0x8000) == 0); + } - instruction[-2] = OP_B_T4a | word1; - instruction[-1] = OP_B_T4b | word2; + static bool isNOP_T1(void* address) + { + uint16_t* instruction = static_cast<uint16_t*>(address); + return instruction[0] == OP_NOP_T1; } - // These functions can be used to splice 16-bit immediates back into previously generated instructions. - static void spliceHi5(uint16_t* where, uint16_t what) + static bool isNOP_T2(void* address) { - uint16_t pattern = (what >> 12) | ((what & 0x0800) >> 1); - *where = (*where & 0xFBF0) | pattern; + uint16_t* instruction = static_cast<uint16_t*>(address); + return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b); } - static void spliceLo11(uint16_t* where, uint16_t what) + + static void linkJumpAbsolute(uint16_t* instruction, void* target) { - uint16_t pattern = ((what & 0x0700) << 4) | (what & 0x00FF); - *where = (*where & 0x8F00) | pattern; + // FIMXE: this should be up in the MacroAssembler layer. :-( + const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; + + ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); + ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); + + ASSERT( (isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) + || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) ); + + intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); + if (((relative << 7) >> 7) == relative) { + // ARM encoding for the top two bits below the sign bit is 'peculiar'. + if (relative >= 0) + relative ^= 0xC00000; + + // All branch offsets should be an even distance. + ASSERT(!(relative & 1)); + // There may be a better way to fix this, but right now put the NOPs first, since in the + // case of an conditional branch this will be coming after an ITTT predicating *three* + // instructions! Looking backwards to modify the ITTT to an IT is not easy, due to + // variable wdith encoding - the previous instruction might *look* like an ITTT but + // actually be the second half of a 2-word op. + instruction[-5] = OP_NOP_T1; + instruction[-4] = OP_NOP_T2a; + instruction[-3] = OP_NOP_T2b; + instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); + instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); + } else { + ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); + ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); + instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); + instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16); + instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); + instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); + instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); + } + } + + static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm) + { + return op | (imm.m_value.i << 10) | imm.m_value.imm4; + } + static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm) + { + return (imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8; } class ARMInstructionFormatter { @@ -1723,8 +1792,11 @@ private: void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm) { - m_buffer.putShort(op | (imm.m_value.i << 10) | imm4); - m_buffer.putShort((imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8); + ARMThumbImmediate newImm = imm; + newImm.m_value.imm4 = imm4; + + m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst(op, newImm)); + m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, newImm)); } void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm) @@ -1749,6 +1821,8 @@ private: private: AssemblerBuffer m_buffer; } m_formatter; + + Vector<LinkRecord> m_jumpsToLink; }; } // namespace JSC diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h index aa8cbb0..7a72b06 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -65,6 +65,7 @@ public: }; static const RegisterID stackPointerRegister = ARMRegisters::sp; + static const RegisterID linkRegister = ARMRegisters::lr; static const Scale ScalePtr = TimesFour; @@ -530,7 +531,7 @@ public: void ret() { - pop(ARMRegisters::pc); + m_assembler.mov_r(ARMRegisters::pc, linkRegister); } void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) @@ -746,11 +747,9 @@ protected: void prepareCall() { - ensureSpace(3 * sizeof(ARMWord), sizeof(ARMWord)); + ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord)); - // S0 might be used for parameter passing - m_assembler.add_r(ARMRegisters::S1, ARMRegisters::pc, ARMAssembler::OP2_IMM | 0x4); - m_assembler.push_r(ARMRegisters::S1); + m_assembler.mov_r(linkRegister, ARMRegisters::pc); } void call32(RegisterID base, int32_t offset) diff --git a/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/JavaScriptCore/assembler/MacroAssemblerARMv7.h index a549604..c479517 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -990,13 +990,15 @@ public: protected: ARMv7Assembler::JmpSrc makeJump() { - return m_assembler.b(); + moveFixedWidthEncoding(Imm32(0), dataTempRegister); + return m_assembler.bx(dataTempRegister); } ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond) { - m_assembler.it(cond); - return m_assembler.b(); + m_assembler.it(cond, true, true); + moveFixedWidthEncoding(Imm32(0), dataTempRegister); + return m_assembler.bx(dataTempRegister); } ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); } ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); } diff --git a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 568260a..3681af8 100644 --- a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/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/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp index 6bac9b9..c915934 100644 --- a/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/JavaScriptCore/bytecode/CodeBlock.cpp @@ -135,11 +135,6 @@ NEVER_INLINE static const char* debugHookName(int debugHookID) return ""; } -static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset) -{ - return it - begin + offset; -} - static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op) { int r0 = (++it)->u.operand; @@ -156,11 +151,11 @@ static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); } -static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op) +static void printConditionalJump(const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) { int r0 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, location + offset); } static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op) @@ -829,6 +824,16 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); break; } + case op_get_by_pname: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int r2 = (++it)->u.operand; + int r3 = (++it)->u.operand; + int r4 = (++it)->u.operand; + int r5 = (++it)->u.operand; + printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), registerName(r4).c_str(), registerName(r5).c_str()); + break; + } case op_put_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; @@ -852,12 +857,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_loop: { int offset = (++it)->u.operand; - printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { @@ -884,56 +889,56 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_jnlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_less: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_loop_if_lesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset); break; } case op_switch_imm: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_char: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_switch_string: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str()); break; } case op_new_func: { @@ -1020,16 +1025,21 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& break; } case op_get_pnames: { - int r0 = (++it)->u.operand; - int r1 = (++it)->u.operand; - printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + int r0 = it[1].u.operand; + int r1 = it[2].u.operand; + int r2 = it[3].u.operand; + int r3 = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_get_pnames) - 1; break; } case op_next_pname: { - int dest = (++it)->u.operand; - int iter = (++it)->u.operand; - int offset = (++it)->u.operand; - printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset)); + int dest = it[1].u.operand; + int iter = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_next_pname) - 1; break; } case op_push_scope: { @@ -1051,7 +1061,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jmp_scopes: { int scopeDelta = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset)); + printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); break; } case op_catch: { @@ -1074,7 +1084,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_jsr: { int retAddrDst = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, location + offset); break; } case op_sret: { diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h index c9196ce..4facbef 100644 --- a/JavaScriptCore/bytecode/Opcode.h +++ b/JavaScriptCore/bytecode/Opcode.h @@ -113,6 +113,7 @@ namespace JSC { macro(op_put_by_id_generic, 8) \ macro(op_del_by_id, 4) \ macro(op_get_by_val, 4) \ + macro(op_get_by_pname, 7) \ macro(op_put_by_val, 4) \ macro(op_del_by_val, 4) \ macro(op_put_by_index, 4) \ @@ -152,8 +153,8 @@ namespace JSC { macro(op_strcat, 4) \ macro(op_to_primitive, 3) \ \ - macro(op_get_pnames, 3) \ - macro(op_next_pname, 4) \ + macro(op_get_pnames, 6) \ + macro(op_next_pname, 7) \ \ macro(op_push_scope, 2) \ macro(op_pop_scope, 1) \ diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 8951ce3..04dae15 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -608,8 +608,9 @@ void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp() PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target) { + size_t begin = instructions().size(); emitOpcode(target->isForward() ? op_jmp : op_loop); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -624,10 +625,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_less); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) { @@ -639,10 +642,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_loop_if_lesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { @@ -653,9 +658,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null && target->isForward()) { @@ -666,16 +673,20 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); + emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -692,10 +703,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnless); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_lesseq) { @@ -707,10 +720,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindBinaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jnlesseq); instructions().append(src1Index); instructions().append(src2Index); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_not) { @@ -721,9 +736,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jtrue); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_eq_null) { @@ -734,9 +751,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jneq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } else if (m_lastOpcodeID == op_neq_null) { @@ -747,34 +766,41 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { rewindUnaryOp(); + + size_t begin = instructions().size(); emitOpcode(op_jeq_null); instructions().append(srcIndex); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } } + size_t begin = instructions().size(); emitOpcode(op_jfalse); instructions().append(cond->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->callFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target) { + size_t begin = instructions().size(); + emitOpcode(op_jneq_ptr); instructions().append(cond->index()); instructions().append(m_scopeChain->globalObject()->d()->applyFunction); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } @@ -1255,6 +1281,19 @@ RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property) { + for (size_t i = m_forInContextStack.size(); i > 0; i--) { + ForInContext& context = m_forInContextStack[i - 1]; + if (context.propertyRegister == property) { + emitOpcode(op_get_by_pname); + instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(property->index()); + instructions().append(context.expectedSubscriptRegister->index()); + instructions().append(context.iterRegister->index()); + instructions().append(context.indexRegister->index()); + return dst; + } + } emitOpcode(op_get_by_val); instructions().append(dst->index()); instructions().append(base->index()); @@ -1718,6 +1757,8 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro } if (nNormalScopes) { + size_t begin = instructions().size(); + // We need to remove a number of dynamic scopes to get to the next // finally block emitOpcode(op_jmp_scopes); @@ -1726,14 +1767,14 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro // If topScope == bottomScope then there isn't actually a finally block // left to emit, so make the jmp_scopes jump directly to the target label if (topScope == bottomScope) { - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } // Otherwise we just use jmp_scopes to pop a group of scopes and go // to the next instruction RefPtr<Label> nextInsn = newLabel(); - instructions().append(nextInsn->offsetFrom(instructions().size())); + instructions().append(nextInsn->bind(begin, instructions().size())); emitLabel(nextInsn.get()); } @@ -1758,27 +1799,47 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetSco if (m_finallyDepth) return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta); + size_t begin = instructions().size(); + emitOpcode(op_jmp_scopes); instructions().append(scopeDelta); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return target; } -RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target) +RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget) { + size_t begin = instructions().size(); + + emitOpcode(op_get_pnames); + instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); + instructions().append(breakTarget->bind(begin, instructions().size())); + return dst; +} + +RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target) +{ + size_t begin = instructions().size(); + emitOpcode(op_next_pname); instructions().append(dst->index()); + instructions().append(base->index()); + instructions().append(i->index()); + instructions().append(size->index()); instructions().append(iter->index()); - instructions().append(target->offsetFrom(instructions().size())); + instructions().append(target->bind(begin, instructions().size())); return dst; } RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end) { #if ENABLE(JIT) - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; #else - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; + HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; #endif m_codeBlock->addExceptionHandler(info); @@ -1798,9 +1859,11 @@ RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSV PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally) { + size_t begin = instructions().size(); + emitOpcode(op_jsr); instructions().append(retAddrDst->index()); - instructions().append(finally->offsetFrom(instructions().size())); + instructions().append(finally->bind(begin, instructions().size())); emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. return finally; } @@ -1870,7 +1933,7 @@ static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1896,7 +1959,7 @@ static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32 // We're emitting this after the clause labels should have been fixed, so // the labels should not be "forward" references ASSERT(!labels[i]->isForward()); - jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); + jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); } } @@ -1910,7 +1973,7 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t ASSERT(nodes[i]->isString()); UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep(); OffsetLocation location; - location.branchOffset = labels[i]->offsetFrom(switchAddress); + location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3); jumpTable.offsetTable.add(clause, location); } } @@ -1921,23 +1984,23 @@ void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, E m_switchContextStack.removeLast(); if (switchInfo.switchType == SwitchInfo::SwitchImmediate) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable(); - prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) { instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable(); - prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max); + prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); } else { ASSERT(switchInfo.switchType == SwitchInfo::SwitchString); instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables(); - instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3); + instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable(); - prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes); + prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes); } } diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 1a83ce9..4648fb5 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -61,6 +61,13 @@ namespace JSC { FinallyContext finallyContext; }; + struct ForInContext { + RefPtr<RegisterID> expectedSubscriptRegister; + RefPtr<RegisterID> iterRegister; + RefPtr<RegisterID> indexRegister; + RefPtr<RegisterID> propertyRegister; + }; + class BytecodeGenerator : public FastAllocBase { public: typedef DeclarationStacks::VarStack VarStack; @@ -312,8 +319,8 @@ namespace JSC { PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*); void emitSubroutineReturn(RegisterID* retAddrSrc); - RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); } - RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target); + RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget); + RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target); RegisterID* emitCatch(RegisterID*, Label* start, Label* end); void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); } @@ -331,6 +338,17 @@ namespace JSC { void pushFinallyContext(Label* target, RegisterID* returnAddrDst); void popFinallyContext(); + void pushOptimisedForIn(RegisterID* expectedBase, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister) + { + ForInContext context = { expectedBase, iter, index, propertyRegister }; + m_forInContextStack.append(context); + } + + void popOptimisedForIn() + { + m_forInContextStack.removeLast(); + } + LabelScope* breakTarget(const Identifier&); LabelScope* continueTarget(const Identifier&); @@ -467,6 +485,7 @@ namespace JSC { Vector<ControlFlowContext> m_scopeContextStack; Vector<SwitchInfo> m_switchContextStack; + Vector<ForInContext> m_forInContextStack; int m_nextGlobalIndex; int m_nextParameterIndex; diff --git a/JavaScriptCore/bytecompiler/Label.h b/JavaScriptCore/bytecompiler/Label.h index 0b3d038..8cab1db 100644 --- a/JavaScriptCore/bytecompiler/Label.h +++ b/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/JavaScriptCore/debugger/DebuggerActivation.h b/JavaScriptCore/debugger/DebuggerActivation.h index dd34265..63cf635 100644 --- a/JavaScriptCore/debugger/DebuggerActivation.h +++ b/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/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index 847b1fa..c77a0f1 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/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,43 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi boolean indicating success (if true) or failure (if false) to register dst. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; - int property = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); Identifier& ident = callFrame->codeBlock()->identifier(property); JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident)); CHECK_FOR_EXCEPTION(); callFrame->r(dst) = result; - ++vPC; + vPC += OPCODE_LENGTH(op_del_by_id); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(op_get_by_pname) { + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int property = vPC[3].u.operand; + int expected = vPC[4].u.operand; + int iter = vPC[5].u.operand; + int i = vPC[6].u.operand; + + JSValue baseValue = callFrame->r(base).jsValue(); + JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); + JSValue subscript = callFrame->r(property).jsValue(); + JSValue expectedSubscript = callFrame->r(expected).jsValue(); + int index = callFrame->r(i).i() - 1; + JSValue result; + int offset = 0; + if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { + callFrame->r(dst) = asObject(baseValue)->getDirectOffset(offset); + vPC += OPCODE_LENGTH(op_get_by_pname); + NEXT_INSTRUCTION(); + } + Identifier propertyName(callFrame, subscript.toString(callFrame)); + result = baseValue.get(callFrame, propertyName); + CHECK_FOR_EXCEPTION(); + callFrame->r(dst) = result; + vPC += OPCODE_LENGTH(op_get_by_pname); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_by_val) { @@ -2478,9 +2452,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 +2482,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 +2496,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 +2532,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 +2543,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 +2563,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 +2578,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 +2599,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 +2613,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 +2627,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 +2644,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 +2660,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 +2676,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 +2685,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 +2694,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 +2703,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 +2712,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 +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 = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); @@ -2774,7 +2748,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 +2762,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 +2775,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 +2786,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 +2798,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi NEXT_INSTRUCTION(); } - ++vPC; + vPC += OPCODE_LENGTH(op_jnless); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jnlesseq) { @@ -2835,9 +2809,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 +2821,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 +2833,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 +2857,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 +2880,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 +2897,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 +2913,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 +2933,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 +2966,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 +3040,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call); NEXT_INSTRUCTION(); } @@ -3076,8 +3050,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 +3123,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 +3194,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi callFrame->r(dst) = returnValue; - vPC += 5; + vPC += OPCODE_LENGTH(op_call_varargs); NEXT_INSTRUCTION(); } @@ -3242,12 +3216,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 +3242,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 +3255,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 +3290,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 +3312,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 +3332,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 +3351,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 +3367,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 +3445,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 +3463,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 +3499,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 +3507,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 +3517,69 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi */ callFrame->setScopeChain(callFrame->scopeChain()->pop()); - ++vPC; + vPC += OPCODE_LENGTH(op_pop_scope); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_get_pnames) { - /* get_pnames dst(r) base(r) + /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset) Creates a property name list for register base and puts it - in register dst. This is not a true JavaScript value, just - a synthetic value used to keep the iteration state in a - register. + in register dst, initializing i and size for iteration. If + base is undefined or null, jumps to breakTarget. */ - int dst = (++vPC)->u.operand; - int base = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int breakTarget = vPC[5].u.operand; - callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue()); - ++vPC; + JSValue v = callFrame->r(base).jsValue(); + if (v.isUndefinedOrNull()) { + vPC += breakTarget; + NEXT_INSTRUCTION(); + } + + JSObject* o = v.toObject(callFrame); + Structure* structure = o->structure(); + JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); + if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) + jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); + + callFrame->r(dst) = jsPropertyNameIterator; + callFrame->r(base) = JSValue(o); + callFrame->r(i) = Register::withInt(0); + callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size()); + vPC += OPCODE_LENGTH(op_get_pnames); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_next_pname) { - /* next_pname dst(r) iter(r) target(offset) + /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) - Tries to copies the next name from property name list in - register iter. If there are names left, then copies one to - register dst, and jumps to offset target. If there are none - left, invalidates the iterator and continues to the next + Copies the next name from the property name list in + register iter to dst, then jumps to offset target. If there are no + names left, invalidates the iterator and continues to the next instruction. */ - int dst = (++vPC)->u.operand; - int iter = (++vPC)->u.operand; - int target = (++vPC)->u.operand; + int dst = vPC[1].u.operand; + int base = vPC[2].u.operand; + int i = vPC[3].u.operand; + int size = vPC[4].u.operand; + int iter = vPC[5].u.operand; + int target = vPC[6].u.operand; JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); - if (JSValue temp = it->next(callFrame)) { - CHECK_FOR_TIMEOUT(); - callFrame->r(dst) = JSValue(temp); - vPC += target; - NEXT_INSTRUCTION(); + while (callFrame->r(i).i() != callFrame->r(size).i()) { + JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); + callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1); + if (key) { + CHECK_FOR_TIMEOUT(); + callFrame->r(dst) = key; + vPC += target; + NEXT_INSTRUCTION(); + } } - it->invalidate(); - ++vPC; + vPC += OPCODE_LENGTH(op_next_pname); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_jmp_scopes) { @@ -3593,8 +3589,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 +3613,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 +3628,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 +3646,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 +3666,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 +3688,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 +3702,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 +3712,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 +3726,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 +3736,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 +3749,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 +3763,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 +3773,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 +3793,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 +3807,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/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h index 3046b28..e17b055 100644 --- a/JavaScriptCore/interpreter/Interpreter.h +++ b/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/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h index 3274fcc..1d15ef0 100644 --- a/JavaScriptCore/jit/ExecutableAllocator.h +++ b/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/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp new file mode 100644 index 0000000..c96ecae --- /dev/null +++ b/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/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp index ea8434e..000e4b8 100644 --- a/JavaScriptCore/jit/JIT.cpp +++ b/JavaScriptCore/jit/JIT.cpp @@ -202,7 +202,6 @@ void JIT::privateCompileMainPass() DEFINE_BINARY_OP(op_less) DEFINE_BINARY_OP(op_lesseq) DEFINE_BINARY_OP(op_urshift) - DEFINE_UNARY_OP(op_get_pnames) DEFINE_UNARY_OP(op_is_boolean) DEFINE_UNARY_OP(op_is_function) DEFINE_UNARY_OP(op_is_number) @@ -240,7 +239,9 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_eq_null) DEFINE_OP(op_get_by_id) DEFINE_OP(op_get_by_val) + DEFINE_OP(op_get_by_pname) DEFINE_OP(op_get_global_var) + DEFINE_OP(op_get_pnames) DEFINE_OP(op_get_scoped_var) DEFINE_OP(op_instanceof) DEFINE_OP(op_jeq_null) @@ -385,6 +386,7 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_eq) DEFINE_SLOWCASE_OP(op_get_by_id) DEFINE_SLOWCASE_OP(op_get_by_val) + DEFINE_SLOWCASE_OP(op_get_by_pname) DEFINE_SLOWCASE_OP(op_instanceof) DEFINE_SLOWCASE_OP(op_jfalse) DEFINE_SLOWCASE_OP(op_jnless) @@ -489,21 +491,21 @@ JITCode JIT::privateCompile() ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character); ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size()); - record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) { unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j]; - record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; + record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.simpleJumpTable->ctiDefault; } } else { ASSERT(record.type == SwitchRecord::String); - record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]); + record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + record.defaultOffset]); StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end(); for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) { unsigned offset = it->second.branchOffset; - it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault; + it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.stringJumpTable->ctiDefault; } } } diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h index 0712743..e19ea17 100644 --- a/JavaScriptCore/jit/JIT.h +++ b/JavaScriptCore/jit/JIT.h @@ -38,6 +38,8 @@ #define JIT_CLASS_ALIGNMENT #endif +#define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(actual), static_cast<int>(expected)); + #include "CodeBlock.h" #include "Interpreter.h" #include "JITCode.h" @@ -249,7 +251,6 @@ namespace JSC { static const RegisterID timeoutCheckRegister = ARMRegisters::r5; static const RegisterID callFrameRegister = ARMRegisters::r4; - static const RegisterID ctiReturnRegister = ARMRegisters::r6; static const RegisterID regT0 = ARMRegisters::r0; static const RegisterID regT1 = ARMRegisters::r1; @@ -386,6 +387,8 @@ namespace JSC { Address addressFor(unsigned index, RegisterID base = callFrameRegister); + void testPrototype(Structure*, JumpList& failureCases); + #if USE(JSVALUE32_64) Address tagFor(unsigned index, RegisterID base = callFrameRegister); Address payloadFor(unsigned index, RegisterID base = callFrameRegister); @@ -425,6 +428,7 @@ namespace JSC { #endif void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset); void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); // Arithmetic opcode helpers @@ -526,6 +530,7 @@ namespace JSC { #endif void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); #if PLATFORM(X86_64) @@ -581,26 +586,26 @@ namespace JSC { #elif PLATFORM(ARM_THUMB2) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 10; - static const int patchOffsetPutByIdExternalLoad = 20; + static const int patchOffsetPutByIdExternalLoad = 26; static const int patchLengthPutByIdExternalLoad = 12; - static const int patchOffsetPutByIdPropertyMapOffset = 40; + static const int patchOffsetPutByIdPropertyMapOffset = 46; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 10; - static const int patchOffsetGetByIdBranchToSlowCase = 20; - static const int patchOffsetGetByIdExternalLoad = 20; + static const int patchOffsetGetByIdBranchToSlowCase = 26; + static const int patchOffsetGetByIdExternalLoad = 26; static const int patchLengthGetByIdExternalLoad = 12; - static const int patchOffsetGetByIdPropertyMapOffset = 40; - static const int patchOffsetGetByIdPutResult = 44; + static const int patchOffsetGetByIdPropertyMapOffset = 46; + static const int patchOffsetGetByIdPutResult = 50; #if ENABLE(OPCODE_SAMPLING) static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE #else static const int patchOffsetGetByIdSlowCaseCall = 28; #endif - static const int patchOffsetOpCallCompareToJump = 10; + static const int patchOffsetOpCallCompareToJump = 16; - static const int patchOffsetMethodCheckProtoObj = 18; - static const int patchOffsetMethodCheckProtoStruct = 28; - static const int patchOffsetMethodCheckPutFunction = 46; + static const int patchOffsetMethodCheckProtoObj = 24; + static const int patchOffsetMethodCheckProtoStruct = 34; + static const int patchOffsetMethodCheckPutFunction = 58; #elif PLATFORM(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; @@ -617,7 +622,7 @@ namespace JSC { #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else - static const int patchOffsetGetByIdSlowCaseCall = 36; + static const int patchOffsetGetByIdSlowCaseCall = 28; #endif static const int patchOffsetOpCallCompareToJump = 12; @@ -638,7 +643,7 @@ namespace JSC { static const int sequenceGetByIdHotPathInstructionSpace = 28; static const int sequenceGetByIdHotPathConstantSpace = 3; // sequenceGetByIdSlowCase - static const int sequenceGetByIdSlowCaseInstructionSpace = 40; + static const int sequenceGetByIdSlowCaseInstructionSpace = 32; static const int sequenceGetByIdSlowCaseConstantSpace = 2; // sequencePutById static const int sequencePutByIdInstructionSpace = 28; @@ -680,6 +685,7 @@ namespace JSC { void emit_op_eq_null(Instruction*); void emit_op_get_by_id(Instruction*); void emit_op_get_by_val(Instruction*); + void emit_op_get_by_pname(Instruction*); void emit_op_get_global_var(Instruction*); void emit_op_get_scoped_var(Instruction*); void emit_op_init_arguments(Instruction*); @@ -713,6 +719,7 @@ namespace JSC { void emit_op_new_func_exp(Instruction*); void emit_op_new_object(Instruction*); void emit_op_new_regexp(Instruction*); + void emit_op_get_pnames(Instruction*); void emit_op_next_pname(Instruction*); void emit_op_not(Instruction*); void emit_op_nstricteq(Instruction*); @@ -768,6 +775,7 @@ namespace JSC { void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp index 7afc1f2..8cda482 100644 --- a/JavaScriptCore/jit/JITArithmetic.cpp +++ b/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/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp index cfaa69f..f7fcc0a 100644 --- a/JavaScriptCore/jit/JITCall.cpp +++ b/JavaScriptCore/jit/JITCall.cpp @@ -614,7 +614,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca END_UNINTERRUPTED_SEQUENCE(sequenceOpCall); addSlowCase(jumpToSlow); - ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump); + ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; // The following is the fast case, only used whan a callee can be linked. diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h index f26457a..93d6ce7 100644 --- a/JavaScriptCore/jit/JITInlineMethods.h +++ b/JavaScriptCore/jit/JITInlineMethods.h @@ -144,7 +144,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) #endif -#if PLATFORM(ARM_THUMB2) +#if PLATFORM(ARM) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -161,7 +161,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) loadPtr(address, linkRegister); } -#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL) +#else // PLATFORM(X86) || PLATFORM(X86_64) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -191,16 +191,13 @@ ALWAYS_INLINE void JIT::restoreArgumentReference() { move(stackPointerRegister, firstArgumentRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); -#if PLATFORM(ARM_TRADITIONAL) - move(ctiReturnRegister, ARMRegisters::lr); -#endif } ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() { #if PLATFORM(X86) // Within a trampoline the return address will be on the stack at this point. addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister); -#elif PLATFORM(ARM_THUMB2) +#elif PLATFORM(ARM) move(stackPointerRegister, firstArgumentRegister); #endif // In the trampoline on x86-64, the first argument register is not overwritten. diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index f362d75..14736cf 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/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 { @@ -267,7 +268,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); @@ -345,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) @@ -366,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) @@ -397,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) @@ -411,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) @@ -442,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) @@ -457,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. @@ -488,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). @@ -512,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); @@ -671,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); @@ -692,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) @@ -785,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); @@ -798,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); @@ -815,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) @@ -826,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); @@ -839,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); @@ -856,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) @@ -870,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(); @@ -881,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); } @@ -897,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(); @@ -908,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); } @@ -920,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) @@ -929,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())); } @@ -1195,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; - load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0); + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); - JITStubCall stubCall(this, cti_op_next_pname); + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + load32(BaseIndex(regT2, regT0, TimesEight), regT2); + store32(Imm32(JSValue::CellTag), tagFor(dst)); + store32(regT2, payloadFor(dst)); + + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + loadPtr(addressFor(base), regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); + + // 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) @@ -1281,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) @@ -1718,7 +1792,6 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // Setup arg4: This is a plain hack move(stackPointerRegister, ARMRegisters::S0); - move(ctiReturnRegister, ARMRegisters::lr); call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data))); addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); @@ -1749,7 +1822,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); restoreReturnAddressBeforeReturn(regT2); @@ -1825,8 +1898,8 @@ void JIT::emit_op_end(Instruction* currentInstruction) void JIT::emit_op_jmp(Instruction* currentInstruction) { unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); - RECORD_JUMP_TARGET(target + 1); + addJump(jump(), target); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_loop(Instruction* currentInstruction) @@ -1834,7 +1907,7 @@ void JIT::emit_op_loop(Instruction* currentInstruction) emitTimeoutCheck(); unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target + 1); + addJump(jump(), target); } void JIT::emit_op_loop_if_less(Instruction* currentInstruction) @@ -1852,7 +1925,7 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThan, regT0, Imm32(op2imm)), target); } else if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); emitJumpSlowCaseIfNotImmediateInteger(regT0); @@ -1861,12 +1934,12 @@ void JIT::emit_op_loop_if_less(Instruction* currentInstruction) #else int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); #endif - addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target + 3); + addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThan, regT0, regT1), target + 3); + addJump(branch32(LessThan, regT0, regT1), target); } } @@ -1885,12 +1958,12 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) #else int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); #endif - addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3); + addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target); } else { emitGetVirtualRegisters(op1, regT0, op2, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3); + addJump(branch32(LessThanOrEqual, regT0, regT1), target); } } @@ -1901,30 +1974,26 @@ void JIT::emit_op_new_object(Instruction* currentInstruction) void JIT::emit_op_instanceof(Instruction* currentInstruction) { + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + // Load the operands (baseVal, proto, and value respectively) into registers. // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); - emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); - emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); + emitGetVirtualRegister(value, regT2); + emitGetVirtualRegister(baseVal, regT0); + emitGetVirtualRegister(proto, regT1); // Check that baseVal & proto are cells. - emitJumpSlowCaseIfNotJSCell(regT0); - emitJumpSlowCaseIfNotJSCell(regT1); + emitJumpSlowCaseIfNotJSCell(regT2, value); + emitJumpSlowCaseIfNotJSCell(regT0, baseVal); + emitJumpSlowCaseIfNotJSCell(regT1, proto); - // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'. + // Check that baseVal 'ImplementsDefaultHasInstance'. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance))); - // If value is not an Object, return false. - Jump valueIsImmediate = emitJumpIfNotJSCell(regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); - - // Check proto is object. - loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); - addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); - // Optimistically load the result true, and start looping. // Initially, regT1 still contains proto and regT2 still contains value. // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain. @@ -1936,16 +2005,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction) loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); Jump isInstance = branchPtr(Equal, regT2, regT1); - branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop); + emitJumpIfJSCell(regT2).linkTo(loop, this); // We get here either by dropping out of the loop, or if value was not an Object. Result is false. - valueIsImmediate.link(this); - valueIsNotObject.link(this); move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0); // isInstance jumps right down to here, to skip setting the result to false (it has already set true). isInstance.link(this); - emitPutVirtualRegister(currentInstruction[1].u.operand); + emitPutVirtualRegister(dst); } void JIT::emit_op_new_func(Instruction* currentInstruction) @@ -2122,9 +2189,9 @@ void JIT::emit_op_loop_if_true(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); @@ -2191,14 +2258,14 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) unsigned target = currentInstruction[2].u.operand; emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target); Jump isNonZero = emitJumpIfImmediateInteger(regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true))))); isNonZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jeq_null(Instruction* currentInstruction) { @@ -2210,16 +2277,16 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); }; void JIT::emit_op_jneq_null(Instruction* currentInstruction) { @@ -2231,16 +2298,16 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2); + addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target); Jump wasNotImmediate = jump(); // Now handle the immediate cases - undefined & null isImmediate.link(this); andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target); wasNotImmediate.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) @@ -2250,9 +2317,9 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) unsigned target = currentInstruction[3].u.operand; emitGetVirtualRegister(src, regT0); - addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target + 3); + addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target); - RECORD_JUMP_TARGET(target + 3); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_jsr(Instruction* currentInstruction) @@ -2260,10 +2327,10 @@ void JIT::emit_op_jsr(Instruction* currentInstruction) int retAddrDst = currentInstruction[1].u.operand; int target = currentInstruction[2].u.operand; DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst)); - addJump(jump(), target + 2); + addJump(jump(), target); m_jsrSites.append(JSRInfo(storeLocation, label())); killLastResultRegister(); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_sret(Instruction* currentInstruction) @@ -2315,13 +2382,13 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target + 2); + addJump(emitJumpIfImmediateInteger(regT0), target); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); isZero.link(this); - RECORD_JUMP_TARGET(target + 2); + RECORD_JUMP_TARGET(target); } void JIT::emit_op_neq(Instruction* currentInstruction) @@ -2372,15 +2439,116 @@ void JIT::emit_op_throw(Instruction* currentInstruction) #endif } +void JIT::emit_op_get_pnames(Instruction* currentInstruction) +{ + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int breakTarget = currentInstruction[5].u.operand; + + JumpList isNotObject; + + emitGetVirtualRegister(base, regT0); + if (!m_codeBlock->isKnownNotImmediate(base)) + isNotObject.append(emitJumpIfNotJSCell(regT0)); + if (base != m_codeBlock->thisRegister()) { + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); + } + + // We could inline the case where you have a valid cache, but + // this call doesn't seem to be hot. + Label isObject(this); + JITStubCall getPnamesStubCall(this, cti_op_get_pnames); + getPnamesStubCall.addArgument(regT0); + getPnamesStubCall.call(dst); + load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3); + store32(Imm32(0), addressFor(i)); + store32(regT3, addressFor(size)); + Jump end = jump(); + + isNotObject.link(this); + move(regT0, regT1); + and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT1); + addJump(branch32(Equal, regT1, Imm32(JSImmediate::FullTagTypeNull)), breakTarget); + + JITStubCall toObjectStubCall(this, cti_to_object); + toObjectStubCall.addArgument(regT0); + toObjectStubCall.call(base); + jump().linkTo(isObject, this); + + end.link(this); +} + void JIT::emit_op_next_pname(Instruction* currentInstruction) { - JITStubCall stubCall(this, cti_op_next_pname); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); + int dst = currentInstruction[1].u.operand; + int base = currentInstruction[2].u.operand; + int i = currentInstruction[3].u.operand; + int size = currentInstruction[4].u.operand; + int it = currentInstruction[5].u.operand; + int target = currentInstruction[6].u.operand; + + JumpList callHasProperty; + + Label begin(this); + load32(addressFor(i), regT0); + Jump end = branch32(Equal, regT0, addressFor(size)); + + // Grab key @ i + loadPtr(addressFor(it), regT1); + loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + +#if USE(JSVALUE64) + loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2); +#else + loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2); +#endif + + emitPutVirtualRegister(dst, regT2); + + // Increment i + add32(Imm32(1), regT0); + store32(regT0, addressFor(i)); + + // Verify that i is valid: + emitGetVirtualRegister(base, regT0); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))))); + + // Test base's prototype chain + loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3); + loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3); + addJump(branchTestPtr(Zero, Address(regT3)), target); + + Label checkPrototype(this); + loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); + callHasProperty.append(emitJumpIfNotJSCell(regT2)); + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3))); + addPtr(Imm32(sizeof(Structure*)), regT3); + branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this); + + // Continue loop. + addJump(jump(), target); + + // Slow case: Ask the object if i is valid. + callHasProperty.link(this); + emitGetVirtualRegister(dst, regT1); + JITStubCall stubCall(this, cti_has_property); + stubCall.addArgument(regT0); + stubCall.addArgument(regT1); stubCall.call(); - Jump endOfIter = branchTestPtr(Zero, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); - addJump(jump(), currentInstruction[3].u.operand + 3); - endOfIter.link(this); + + // Test for valid key. + addJump(branchTest32(NonZero, regT0), target); + jump().linkTo(begin, this); + + // End of loop. + end.link(this); } void JIT::emit_op_push_scope(Instruction* currentInstruction) @@ -2464,8 +2632,8 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_jmp_scopes); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); stubCall.call(); - addJump(jump(), currentInstruction[2].u.operand + 2); - RECORD_JUMP_TARGET(currentInstruction[2].u.operand + 2); + addJump(jump(), currentInstruction[2].u.operand); + RECORD_JUMP_TARGET(currentInstruction[2].u.operand); } void JIT::emit_op_switch_imm(Instruction* currentInstruction) @@ -2718,14 +2886,14 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(op2, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else if (isOperandConstantImmediateInt(op1)) { linkSlowCase(iter); JITStubCall stubCall(this, cti_op_loop_if_less); stubCall.addArgument(op1, regT2); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2733,7 +2901,7 @@ void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowC stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } } @@ -2747,7 +2915,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(regT0); stubCall.addArgument(currentInstruction[2].u.operand, regT2); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); + emitJumpSlowToHot(branchTest32(NonZero, regT0), target); } else { linkSlowCase(iter); linkSlowCase(iter); @@ -2755,7 +2923,7 @@ 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); } } @@ -2783,7 +2951,7 @@ void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowC JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2801,7 +2969,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted! + emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted! } void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2818,7 +2986,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr JITStubCall stubCall(this, cti_op_jtrue); stubCall.addArgument(regT0); stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2); + emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); } void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -2884,16 +3052,20 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); + unsigned dst = currentInstruction[1].u.operand; + unsigned value = currentInstruction[2].u.operand; + unsigned baseVal = currentInstruction[3].u.operand; + unsigned proto = currentInstruction[4].u.operand; + + linkSlowCaseIfNotJSCell(iter, value); + linkSlowCaseIfNotJSCell(iter, baseVal); + linkSlowCaseIfNotJSCell(iter, proto); linkSlowCase(iter); JITStubCall stubCall(this, cti_op_instanceof); - stubCall.addArgument(currentInstruction[2].u.operand, regT2); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.addArgument(currentInstruction[4].u.operand, regT2); - stubCall.call(currentInstruction[1].u.operand); + stubCall.addArgument(value, regT2); + stubCall.addArgument(baseVal, regT2); + stubCall.addArgument(proto, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp index 9edfd01..bf367a6 100644 --- a/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -33,6 +33,7 @@ #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" +#include "JSPropertyNameIterator.h" #include "Interpreter.h" #include "LinkBuffer.h" #include "RepatchBuffer.h" @@ -521,22 +522,26 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res load32(Address(temp, offset + 4), resultTag); } +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure))); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack. JumpList failureCases; failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); - - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(oldStructure))); + failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); + testPrototype(oldStructure, failureCases); // Verify that nothing in the prototype chain has a setter for this property. - for (RefPtr<Structure>* it = chain->head(); *it; ++it) { - loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2); - loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(it->get()))); - } + for (RefPtr<Structure>* it = chain->head(); *it; ++it) + testPrototype(it->get(), failureCases); // Reallocate property storage if needed. Call callTarget; @@ -930,6 +935,69 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) +void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset) +{ + ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSValue) == 8); + + Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + Jump finishedLoad = jump(); + notUsingInlineStorage.link(this); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); + loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + finishedLoad.link(this); +} + +void JIT::emit_op_get_by_pname(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitLoad2(property, regT1, regT0, base, regT3, regT2); + emitJumpSlowCaseIfNotJSCell(property, regT1); + addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected))); + // Property registers are now available as the property is known + emitJumpSlowCaseIfNotJSCell(base, regT3); + emitLoadPayload(iter, regT1); + + // Test base's structure + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); + addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + load32(addressFor(i), regT3); + sub32(Imm32(1), regT3); + addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); + compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3); + + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCaseIfNotJSCell(iter, property); + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base); + stubCall.addArgument(property); + stubCall.call(dst); +} + #else // USE(JSVALUE32_64) void JIT::emit_op_get_by_val(Instruction* currentInstruction) @@ -963,6 +1031,48 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitPutVirtualRegister(dst); } +void JIT::emit_op_get_by_pname(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitGetVirtualRegister(property, regT0); + addSlowCase(branchPtr(NotEqual, regT0, addressFor(expected))); + emitGetVirtualRegisters(base, regT0, iter, regT1); + emitJumpSlowCaseIfNotJSCell(regT0, base); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + load32(addressFor(i), regT3); + sub32(Imm32(1), regT3); + addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); + compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1); + + emitPutVirtualRegister(dst, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); +} + void JIT::emit_op_put_by_val(Instruction* currentInstruction) { unsigned base = currentInstruction[1].u.operand; @@ -1128,9 +1238,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) Jump match = jump(); - ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); - ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct); - ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); // Link the failure cases here. notCell.link(this); @@ -1197,22 +1307,22 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert DataLabelPtr structureToCompare; Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); addSlowCase(structureCheck); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure); - ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase) Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad); DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset); Label putResult(this); END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); - ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); } void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1247,7 +1357,7 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); - ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); + ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall); // Track the location of the call; this will be used to recover patch information. m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; @@ -1278,19 +1388,19 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over. DataLabelPtr structureToCompare; addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)))); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure); // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used. Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad); DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset)); END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetPutByIdPropertyMapOffset); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1347,35 +1457,41 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res } } +void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) +{ + ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); + + Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); + loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); + Jump finishedLoad = jump(); + notUsingInlineStorage.link(this); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); + loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); + finishedLoad.link(this); +} + +void JIT::testPrototype(Structure* structure, JumpList& failureCases) +{ + if (structure->m_prototype.isNull()) + return; + + move(ImmPtr(&asCell(structure->m_prototype)->m_structure), regT2); + move(ImmPtr(asCell(structure->m_prototype)->m_structure), regT3); + failureCases.append(branchPtr(NotEqual, Address(regT2), regT3)); +} + void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) { JumpList failureCases; // Check eax is an object of the right Structure. failureCases.append(emitJumpIfNotJSCell(regT0)); failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); - JumpList successCases; + testPrototype(oldStructure, failureCases); - // 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))); - - 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/JavaScriptCore/jit/JITStubCall.h b/JavaScriptCore/jit/JITStubCall.h index cb5354b..c5ed9e3 100644 --- a/JavaScriptCore/jit/JITStubCall.h +++ b/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/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index c7257af..c999618 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -535,37 +535,27 @@ asm volatile ( SYMBOL_STRING(ctiTrampoline) ":" "\n" "stmdb sp!, {r1-r3}" "\n" "stmdb sp!, {r4-r8, lr}" "\n" - "mov r6, pc" "\n" - "add r6, r6, #40" "\n" - "sub sp, sp, #32" "\n" - "ldr r4, [sp, #60]" "\n" + "sub sp, sp, #36" "\n" + "mov r4, r2" "\n" "mov r5, #512" "\n" - // r0 contains the code - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" + "mov lr, pc" "\n" "mov pc, r0" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" - - // the return instruction - "ldr pc, [sp], #4" "\n" ); asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" - "mov lr, r6" "\n" - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" - "b " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" // Both has the same return sequence ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" @@ -700,11 +690,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; @@ -780,17 +774,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); } @@ -908,6 +898,22 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \ +#elif PLATFORM(ARM_TRADITIONAL) && COMPILER(GCC) + +#define DEFINE_STUB_FUNCTION(rtype, op) \ + extern "C" { \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \ + }; \ + asm volatile ( \ + ".globl " SYMBOL_STRING(cti_##op) "\n" \ + SYMBOL_STRING(cti_##op) ":" "\n" \ + "str lr, [sp, #32]" "\n" \ + "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ + "ldr lr, [sp, #32]" "\n" \ + "mov pc, lr" "\n" \ + ); \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) + #else #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif @@ -1332,15 +1338,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)) @@ -1418,7 +1420,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(); @@ -2656,7 +2658,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()); } @@ -2671,18 +2673,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) @@ -3023,6 +3029,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/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index daae043..69776cb 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -63,6 +63,7 @@ namespace JSC { int32_t asInt32; JSValue jsValue() { return JSValue::decode(asEncodedJSValue); } + JSObject* jsObject() { return static_cast<JSObject*>(asPointer); } Identifier& identifier() { return *static_cast<Identifier*>(asPointer); } int32_t int32() { return asInt32; } CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); } @@ -162,6 +163,8 @@ namespace JSC { JITStubArg padding; // Unused JITStubArg args[7]; + ReturnAddressPtr thunkReturnAddress; + void* preservedR4; void* preservedR5; void* preservedR6; @@ -172,11 +175,13 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; JSValue* exception; + + // These arguments passed on the stack. Profiler** enabledProfilerReference; JSGlobalData* globalData; // When JIT code makes a call, it pushes its return address just below the rest of the stack. - ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } + ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; #else #error "JITStackFrame not defined for this platform." @@ -285,7 +290,6 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION); @@ -307,6 +311,7 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION); + EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION); @@ -332,6 +337,7 @@ extern "C" { int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION); int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION); int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION); + int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION); diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp index 9399b1a..b6bc0aa 100644 --- a/JavaScriptCore/jsc.cpp +++ b/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/JavaScriptCore/jsc.pro b/JavaScriptCore/jsc.pro index ba880ff..c6efabc 100644 --- a/JavaScriptCore/jsc.pro +++ b/JavaScriptCore/jsc.pro @@ -29,3 +29,7 @@ lessThan(QT_MINOR_VERSION, 4) { *-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 *-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 + +symbian { + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y index 85fd163..6d953df 100644 --- a/JavaScriptCore/parser/Grammar.y +++ b/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/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp index 785b219..df30838 100644 --- a/JavaScriptCore/parser/Lexer.cpp +++ b/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/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h index 174e05a..c76696c 100644 --- a/JavaScriptCore/parser/Lexer.h +++ b/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/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp index 3bd318a..45009dc 100644 --- a/JavaScriptCore/parser/Nodes.cpp +++ b/JavaScriptCore/parser/Nodes.cpp @@ -1468,20 +1468,24 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds if (!m_lexpr->isLocation()) return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference."); - RefPtr<Label> continueTarget = generator.newLabel(); - generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_init) generator.emitNode(generator.ignoredResult(), m_init); - RegisterID* forInBase = generator.emitNode(m_expr); - RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase); + + RefPtr<RegisterID> base = generator.newTemporary(); + generator.emitNode(base.get(), m_expr); + RefPtr<RegisterID> i = generator.newTemporary(); + RefPtr<RegisterID> size = generator.newTemporary(); + RefPtr<RegisterID> expectedSubscript; + RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); generator.emitJump(scope->continueTarget()); RefPtr<Label> loopStart = generator.newLabel(); generator.emitLabel(loopStart.get()); RegisterID* propertyName; + bool optimizedForinAccess = false; if (m_lexpr->isResolveNode()) { const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); propertyName = generator.registerFor(ident); @@ -1492,6 +1496,10 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitExpressionInfo(divot(), startOffset(), endOffset()); generator.emitPutById(base, ident, propertyName); + } else { + expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); + generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); + optimizedForinAccess = true; } } else if (m_lexpr->isDotAccessorNode()) { DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); @@ -1516,8 +1524,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitNode(dst, m_statement); + if (optimizedForinAccess) + generator.popOptimisedForIn(); + generator.emitLabel(scope->continueTarget()); - generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get()); + generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); generator.emitLabel(scope->breakTarget()); return dst; diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h index 5be84a2..9b674a2 100644 --- a/JavaScriptCore/runtime/Arguments.h +++ b/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/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp index 0237fd4..fb44494 100644 --- a/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/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/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h index 28f796a..69c2e51 100644 --- a/JavaScriptCore/runtime/BooleanObject.h +++ b/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/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp index 1a5eb89..1b238d9 100644 --- a/JavaScriptCore/runtime/Collector.cpp +++ b/JavaScriptCore/runtime/Collector.cpp @@ -1228,6 +1228,10 @@ static const char* typeName(JSCell* cell) #endif if (cell->isGetterSetter()) return "gettersetter"; + if (cell->isAPIValueWrapper()) + return "value wrapper"; + if (cell->isPropertyNameIterator()) + return "for-in iterator"; ASSERT(cell->isObject()); const ClassInfo* info = cell->classInfo(); return info ? info->className : "Object"; diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h index 2ce13dc..9ca9d18 100644 --- a/JavaScriptCore/runtime/Collector.h +++ b/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); diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp index f9b7d84..9908fef 100644 --- a/JavaScriptCore/runtime/DateConstructor.cpp +++ b/JavaScriptCore/runtime/DateConstructor.cpp @@ -112,9 +112,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args) } } - DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure()); - result->setInternalValue(jsNumber(exec, timeClip(value))); - return result; + return new (exec) DateInstance(exec, value); } static JSObject* constructWithDateConstructor(ExecState* exec, JSObject*, const ArgList& args) diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp index 4cd58f5..d4c9ef7 100644 --- a/JavaScriptCore/runtime/DateInstance.cpp +++ b/JavaScriptCore/runtime/DateInstance.cpp @@ -32,95 +32,43 @@ using namespace WTF; namespace JSC { -struct DateInstance::Cache { - double m_gregorianDateTimeCachedForMS; - GregorianDateTime m_cachedGregorianDateTime; - double m_gregorianDateTimeUTCCachedForMS; - GregorianDateTime m_cachedGregorianDateTimeUTC; -}; - const ClassInfo DateInstance::info = {"Date", 0, 0, 0}; -DateInstance::DateInstance(NonNullPassRefPtr<Structure> structure) +DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure) : JSWrapperObject(structure) - , m_cache(0) { + setInternalValue(jsNaN(exec)); } DateInstance::DateInstance(ExecState* exec, double time) : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) - , m_cache(0) { setInternalValue(jsNumber(exec, timeClip(time))); } -DateInstance::~DateInstance() +bool DateInstance::getGregorianDateTime(ExecState* exec, bool outputIsUTC, GregorianDateTime& t) const { - delete m_cache; -} + double milli = internalNumber(); + if (isnan(milli)) + return false; -void DateInstance::msToGregorianDateTime(double milli, bool outputIsUTC, GregorianDateTime& t) const -{ - if (!m_cache) { - m_cache = new Cache; - m_cache->m_gregorianDateTimeCachedForMS = NaN; - m_cache->m_gregorianDateTimeUTCCachedForMS = NaN; - } + if (!m_data) + m_data = exec->globalData().dateInstanceCache.add(milli); if (outputIsUTC) { - if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) { - WTF::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC); - m_cache->m_gregorianDateTimeUTCCachedForMS = milli; + if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) { + WTF::msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC); + m_data->m_gregorianDateTimeUTCCachedForMS = milli; } - t.copyFrom(m_cache->m_cachedGregorianDateTimeUTC); + t.copyFrom(m_data->m_cachedGregorianDateTimeUTC); } else { - if (m_cache->m_gregorianDateTimeCachedForMS != milli) { - WTF::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime); - m_cache->m_gregorianDateTimeCachedForMS = milli; + if (m_data->m_gregorianDateTimeCachedForMS != milli) { + WTF::msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime); + m_data->m_gregorianDateTimeCachedForMS = milli; } - t.copyFrom(m_cache->m_cachedGregorianDateTime); + t.copyFrom(m_data->m_cachedGregorianDateTime); } -} -bool DateInstance::getTime(GregorianDateTime& t, int& offset) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return false; - - msToGregorianDateTime(milli, false, t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(GregorianDateTime& t) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return false; - - msToGregorianDateTime(milli, true, t); - return true; -} - -bool DateInstance::getTime(double& milli, int& offset) const -{ - milli = internalNumber(); - if (isnan(milli)) - return false; - - GregorianDateTime t; - msToGregorianDateTime(milli, false, t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(double& milli) const -{ - milli = internalNumber(); - if (isnan(milli)) - return false; - return true; } diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h index 36d90b1..38b321c 100644 --- a/JavaScriptCore/runtime/DateInstance.h +++ b/JavaScriptCore/runtime/DateInstance.h @@ -32,27 +32,26 @@ namespace JSC { class DateInstance : public JSWrapperObject { public: DateInstance(ExecState*, double); - explicit DateInstance(NonNullPassRefPtr<Structure>); - virtual ~DateInstance(); + explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>); double internalNumber() const { return internalValue().uncheckedGetNumber(); } - bool getTime(WTF::GregorianDateTime&, int& offset) const; - bool getUTCTime(WTF::GregorianDateTime&) const; - bool getTime(double& milliseconds, int& offset) const; - bool getUTCTime(double& milliseconds) const; - static JS_EXPORTDATA const ClassInfo info; - void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const; + bool getGregorianDateTime(ExecState*, bool outputIsUTC, WTF::GregorianDateTime&) const; + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + } + + protected: + static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; private: virtual const ClassInfo* classInfo() const { return &info; } - using JSWrapperObject::internalValue; - - struct Cache; - mutable Cache* m_cache; + mutable RefPtr<DateInstanceData> m_data; }; DateInstance* asDateInstance(JSValue); diff --git a/JavaScriptCore/runtime/DateInstanceCache.h b/JavaScriptCore/runtime/DateInstanceCache.h new file mode 100644 index 0000000..b626c1d --- /dev/null +++ b/JavaScriptCore/runtime/DateInstanceCache.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DateInstanceCache_h +#define DateInstanceCache_h + +#include <wtf/DateMath.h> +#include <wtf/HashFunctions.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace JSC { + + extern const double NaN; + + class DateInstanceData : public RefCounted<DateInstanceData> { + public: + static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); } + + double m_gregorianDateTimeCachedForMS; + WTF::GregorianDateTime m_cachedGregorianDateTime; + double m_gregorianDateTimeUTCCachedForMS; + WTF::GregorianDateTime m_cachedGregorianDateTimeUTC; + + private: + DateInstanceData() + : m_gregorianDateTimeCachedForMS(NaN) + , m_gregorianDateTimeUTCCachedForMS(NaN) + { + } + }; + + class DateInstanceCache { + public: + DateInstanceCache() + { + for (size_t i = 0; i < cacheSize; ++i) + m_cache[i].key = NaN; + } + + DateInstanceData* add(double d) + { + CacheEntry& entry = lookup(d); + if (d == entry.key) + return entry.value.get(); + + entry.key = d; + entry.value = DateInstanceData::create(); + return entry.value.get(); + } + + private: + static const size_t cacheSize = 64; + + struct CacheEntry { + double key; + RefPtr<DateInstanceData> value; + }; + + CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } + + CacheEntry m_cache[cacheSize]; + }; + +} // namespace JSC + +#endif // DateInstanceCache_h diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp index e46ab67..3f3e1f9 100644 --- a/JavaScriptCore/runtime/DatePrototype.cpp +++ b/JavaScriptCore/runtime/DatePrototype.cpp @@ -251,11 +251,12 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L return jsNontrivialString(exec, timebuffer); } -static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList&) +static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format, const ArgList&) { GregorianDateTime gregorianDateTime; - const bool notUTC = false; - dateObject->msToGregorianDateTime(timeInMilliseconds, notUTC, gregorianDateTime); + const bool outputIsUTC = false; + if (!dateObject->getGregorianDateTime(exec, outputIsUTC, gregorianDateTime)) + return jsNontrivialString(exec, "Invalid Date"); return formatLocaleDate(exec, gregorianDateTime, format); } @@ -396,9 +397,8 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState // ECMA 15.9.4 DatePrototype::DatePrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure) - : DateInstance(structure) + : DateInstance(exec, structure) { - setInternalValue(jsNaN(exec)); // The constructor will be added later, after DateConstructor has been built. } @@ -420,16 +420,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -437,16 +435,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -454,19 +450,17 @@ JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (!isfinite(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds) // 6 for formatting and one for null termination = 27. We add one extra character to allow us to force null termination. char buffer[28]; - snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(milli, 1000))); + snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000))); buffer[sizeof(buffer) - 1] = 0; return jsNontrivialString(exec, buffer); } @@ -476,15 +470,13 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); return jsNontrivialString(exec, formatDate(t)); } @@ -493,16 +485,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -511,11 +501,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JS return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDateAndTime, args); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -524,11 +510,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDate, args); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -537,11 +519,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); - - return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args); + return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleTime, args); } JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -549,12 +527,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); - - return jsNumber(exec, milli); + return asDateInstance(thisValue)->internalValue(); } JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -562,15 +535,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, 1900 + t.year); } @@ -579,15 +550,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JS if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, 1900 + t.year); } @@ -596,16 +565,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); - return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc)); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, outputIsUTC)); } JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -613,15 +580,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.month); } @@ -630,15 +595,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.month); } @@ -647,15 +610,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.monthDay); } @@ -664,15 +625,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.monthDay); } @@ -681,15 +640,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue th if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.weekDay); } @@ -698,15 +655,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.weekDay); } @@ -715,15 +670,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.hour); } @@ -732,15 +685,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSVal if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.hour); } @@ -749,15 +700,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.minute); } @@ -766,15 +715,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSV if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.minute); } @@ -783,15 +730,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValu if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.second); } @@ -800,15 +745,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSV if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = true; + const bool outputIsUTC = true; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, t.second); } @@ -847,15 +790,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); return jsNumber(exec, -gmtoffset(t) / minutesPerHour); } @@ -890,7 +831,7 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const double ms = milli - secs * msPerSecond; GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); + thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) { JSValue result = jsNaN(exec); @@ -922,11 +863,11 @@ static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const if (numArgsToUse == 3 && isnan(milli)) // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear) // the time must be reset to +0 if it is NaN. - thisDateObj->msToGregorianDateTime(0, true, t); + WTF::msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; - thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); + thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); } if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) { @@ -1029,7 +970,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); if (args.isEmpty()) { @@ -1045,11 +986,11 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t if (isnan(milli)) // Based on ECMA 262 B.2.5 (setYear) // the time must be reset to +0 if it is NaN. - thisDateObj->msToGregorianDateTime(0, true, t); + WTF::msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; - thisDateObj->msToGregorianDateTime(milli, utc, t); + thisDateObj->getGregorianDateTime(exec, outputIsUTC, t); } bool ok = true; @@ -1061,7 +1002,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t } t.year = (year > 99 || year < 0) ? year - 1900 : year; - JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc)); + JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, outputIsUTC)); thisDateObj->setInternalValue(result); return result; } @@ -1071,15 +1012,13 @@ JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue t if (!thisValue.inherits(&DateInstance::info)) return throwError(exec, TypeError); - const bool utc = false; + const bool outputIsUTC = false; DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return jsNaN(exec); GregorianDateTime t; - thisDateObj->msToGregorianDateTime(milli, utc, t); + if (!thisDateObj->getGregorianDateTime(exec, outputIsUTC, t)) + return jsNaN(exec); // NOTE: IE returns the full year even in getYear. return jsNumber(exec, t.year); diff --git a/JavaScriptCore/runtime/DatePrototype.h b/JavaScriptCore/runtime/DatePrototype.h index caed2d4..f565775 100644 --- a/JavaScriptCore/runtime/DatePrototype.h +++ b/JavaScriptCore/runtime/DatePrototype.h @@ -39,8 +39,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags; + }; } // namespace JSC diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h index 0e38549..d1d6a1d 100644 --- a/JavaScriptCore/runtime/FunctionPrototype.h +++ b/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/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h index 73dd854..68e9ea3 100644 --- a/JavaScriptCore/runtime/GetterSetter.h +++ b/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/JavaScriptCore/runtime/GlobalEvalFunction.h b/JavaScriptCore/runtime/GlobalEvalFunction.h index b62ad3e..389b1c3 100644 --- a/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/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/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h index fdd5cc1..de9a1d6 100644 --- a/JavaScriptCore/runtime/InternalFunction.h +++ b/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/JavaScriptCore/runtime/JSAPIValueWrapper.h b/JavaScriptCore/runtime/JSAPIValueWrapper.h index 88a8493..aca550e 100644 --- a/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ b/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/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h index 583b988..ee98191 100644 --- a/JavaScriptCore/runtime/JSActivation.h +++ b/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/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h index 66b5a1d..8c22451 100644 --- a/JavaScriptCore/runtime/JSArray.h +++ b/JavaScriptCore/runtime/JSArray.h @@ -87,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); @@ -157,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/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp index 90d39f0..5e5003b 100644 --- a/JavaScriptCore/runtime/JSByteArray.cpp +++ b/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/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h index 006f4a2..fe6e124 100644 --- a/JavaScriptCore/runtime/JSByteArray.h +++ b/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/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp index aa93252..fae056e 100644 --- a/JavaScriptCore/runtime/JSCell.cpp +++ b/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/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h index 503c6c4..722ae33 100644 --- a/JavaScriptCore/runtime/JSCell.h +++ b/JavaScriptCore/runtime/JSCell.h @@ -59,6 +59,7 @@ namespace JSC { virtual bool isGetterSetter() const; bool inherits(const ClassInfo*) const; virtual bool isAPIValueWrapper() const { return false; } + virtual bool isPropertyNameIterator() const { return false; } Structure* structure() const; @@ -112,14 +113,6 @@ namespace JSC { Structure* m_structure; }; - // FIXME: We should deprecate this and just use JSValue::asCell() instead. - JSCell* asCell(JSValue); - - inline JSCell* asCell(JSValue value) - { - return value.asCell(); - } - inline JSCell::JSCell(Structure* structure) : m_structure(structure) { @@ -162,11 +155,7 @@ namespace JSC { inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } // --- JSValue inlines ---------------------------- @@ -342,11 +331,6 @@ namespace JSC { append(value.asCell()); } - inline void Structure::markAggregate(MarkStack& markStack) - { - markStack.append(m_prototype); - } - inline Heap* Heap::heap(JSValue v) { if (!v.isCell()) diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h index a9ac63e..fcac9aa 100644 --- a/JavaScriptCore/runtime/JSFunction.h +++ b/JavaScriptCore/runtime/JSFunction.h @@ -61,17 +61,20 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } NativeFunction nativeFunction() { - return *reinterpret_cast<NativeFunction*>(m_data); + return *WTF::bitwise_cast<NativeFunction*>(m_data); } virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); + protected: + const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags; + private: JSFunction(NonNullPassRefPtr<Structure>); @@ -94,7 +97,7 @@ namespace JSC { ScopeChain& scopeChain() { ASSERT(!isHostFunctionNonInline()); - return *reinterpret_cast<ScopeChain*>(m_data); + return *WTF::bitwise_cast<ScopeChain*>(m_data); } void clearScopeChain() { @@ -109,11 +112,11 @@ namespace JSC { void setScopeChain(const ScopeChain& sc) { ASSERT(!isHostFunctionNonInline()); - *reinterpret_cast<ScopeChain*>(m_data) = sc; + *WTF::bitwise_cast<ScopeChain*>(m_data) = sc; } void setNativeFunction(NativeFunction func) { - *reinterpret_cast<NativeFunction*>(m_data) = func; + *WTF::bitwise_cast<NativeFunction*>(m_data) = func; } unsigned char m_data[sizeof(void*)]; }; diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h index 3ad90ad..d2aa2da 100644 --- a/JavaScriptCore/runtime/JSGlobalData.h +++ b/JavaScriptCore/runtime/JSGlobalData.h @@ -30,6 +30,7 @@ #define JSGlobalData_h #include "Collector.h" +#include "DateInstanceCache.h" #include "ExecutableAllocator.h" #include "JITStubs.h" #include "JSValue.h" @@ -116,7 +117,8 @@ namespace JSC { const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark. SmallStrings smallStrings; NumericStrings numericStrings; - + DateInstanceCache dateInstanceCache; + #if ENABLE(ASSEMBLER) ExecutableAllocator executableAllocator; #endif diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp index 3bb281e..cf3f1d1 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/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/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h index 2106783..720d3a5 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.h +++ b/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/JavaScriptCore/runtime/JSNotAnObject.h b/JavaScriptCore/runtime/JSNotAnObject.h index 0d9aca6..a271c4e 100644 --- a/JavaScriptCore/runtime/JSNotAnObject.h +++ b/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/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h index 6a48081..309488f 100644 --- a/JavaScriptCore/runtime/JSNumberCell.h +++ b/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/JavaScriptCore/runtime/JSONObject.h b/JavaScriptCore/runtime/JSONObject.h index 65c9803..ec3fa40 100644 --- a/JavaScriptCore/runtime/JSONObject.h +++ b/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/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp index db2a9b2..6932ded 100644 --- a/JavaScriptCore/runtime/JSObject.cpp +++ b/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/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h index 84b5f4b..5a89c40 100644 --- a/JavaScriptCore/runtime/JSObject.h +++ b/JavaScriptCore/runtime/JSObject.h @@ -202,15 +202,17 @@ namespace JSC { void allocatePropertyStorageInline(size_t oldSize, size_t newSize); bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } - static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; - static const size_t nonInlineBaseStorageCapacity = 16; + static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; + static const unsigned nonInlineBaseStorageCapacity = 16; static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = 0; + void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { @@ -368,7 +370,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - if (structure()->typeInfo().hasStandardGetOwnPropertySlot()) + if (!structure()->typeInfo().overridesGetOwnPropertySlot()) return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot); return getOwnPropertySlot(exec, propertyName, slot); } @@ -682,7 +684,7 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) { JSCell::markChildren(markStack); - m_structure->markAggregate(markStack); + markStack.append(prototype()); PropertyStorage storage = propertyStorage(); size_t storageSize = m_structure->propertyStorageSize(); diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index e08a3d9..6fd0344 100644 --- a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -29,26 +29,61 @@ #include "config.h" #include "JSPropertyNameIterator.h" +#include "JSGlobalObject.h" + namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); -JSPropertyNameIterator::~JSPropertyNameIterator() +JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { + ASSERT(!o->structure()->enumerationCache() || + o->structure()->enumerationCache()->cachedStructure() != o->structure() || + o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); + + PropertyNameArray propertyNames(exec); + o->getPropertyNames(exec, propertyNames); + size_t numCacheableSlots = 0; + if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() && + !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames()) + numCacheableSlots = o->structure()->propertyStorageSize(); + + JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); + + if (o->structure()->isDictionary()) + return jsPropertyNameIterator; + + if (o->structure()->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + + size_t count = normalizePrototypeChain(exec, o); + StructureChain* structureChain = o->structure()->prototypeChain(exec); + RefPtr<Structure>* structure = structureChain->head(); + for (size_t i = 0; i < count; ++i) { + if (structure[i]->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + } + + jsPropertyNameIterator->setCachedPrototypeChain(structureChain); + jsPropertyNameIterator->setCachedStructure(o->structure()); + o->structure()->setEnumerationCache(jsPropertyNameIterator); + return jsPropertyNameIterator; } -void JSPropertyNameIterator::markChildren(MarkStack& markStack) +JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i) { - JSCell::markChildren(markStack); - if (m_object) - markStack.append(m_object); + JSValue& identifier = m_jsStrings[i]; + if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec)) + return identifier; + + if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value()))) + return JSValue(); + return identifier; } -void JSPropertyNameIterator::invalidate() +void JSPropertyNameIterator::markChildren(MarkStack& markStack) { - ASSERT(m_position == m_end); - m_object = 0; - m_data.clear(); + markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues); } } // namespace JSC diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h index d2849a8..529ae8b 100644 --- a/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -31,6 +31,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Operations.h" #include "PropertyNameArray.h" namespace JSC { @@ -39,73 +40,63 @@ namespace JSC { class JSObject; class JSPropertyNameIterator : public JSCell { + friend class JIT; + public: - static JSPropertyNameIterator* create(ExecState*, JSValue); + static JSPropertyNameIterator* create(ExecState*, JSObject*); + + static PassRefPtr<Structure> createStructure(JSValue prototype) + { + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren)); + } - virtual ~JSPropertyNameIterator(); + virtual bool isPropertyNameIterator() const { return true; } virtual void markChildren(MarkStack&); - JSValue next(ExecState*); - void invalidate(); - - static PassRefPtr<Structure> createStructure(JSValue prototype) + bool getOffset(size_t i, int& offset) { - return Structure::create(prototype, TypeInfo(CompoundType)); + if (i >= m_numCacheableSlots) + return false; + offset = i; + return true; } + + JSValue get(ExecState*, JSObject*, size_t i); + size_t size() { return m_jsStringsSize; } + + void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } + Structure* cachedStructure() { return m_cachedStructure; } + + void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } + StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } + private: - JSPropertyNameIterator(ExecState*); - JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); + JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot); - JSObject* m_object; - RefPtr<PropertyNameArrayData> m_data; - PropertyNameArrayData::const_iterator m_position; - PropertyNameArrayData::const_iterator m_end; + Structure* m_cachedStructure; + RefPtr<StructureChain> m_cachedPrototypeChain; + uint32_t m_numCacheableSlots; + uint32_t m_jsStringsSize; + OwnArrayPtr<JSValue> m_jsStrings; }; -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec) +inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots) : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(0) - , m_position(0) - , m_end(0) + , m_cachedStructure(0) + , m_numCacheableSlots(numCacheableSlots) + , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) + , m_jsStrings(new JSValue[m_jsStringsSize]) { + PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); + for (size_t i = 0; i < m_jsStringsSize; ++i) + m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring()); } -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData) - : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(object) - , m_data(propertyNameArrayData) - , m_position(m_data->begin()) - , m_end(m_data->end()) -{ -} - -inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v) +inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache) { - if (v.isUndefinedOrNull()) - return new (exec) JSPropertyNameIterator(exec); - - JSObject* o = v.toObject(exec); - PropertyNameArray propertyNames(exec); - o->getPropertyNames(exec, propertyNames); - return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData()); -} - -inline JSValue JSPropertyNameIterator::next(ExecState* exec) -{ - if (m_position == m_end) - return JSValue(); - - if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec)) - return jsOwnedString(exec, (*m_position++).ustring()); - - do { - if (m_object->hasProperty(exec, *m_position)) - return jsOwnedString(exec, (*m_position++).ustring()); - m_position++; - } while (m_position != m_end); - - return JSValue(); + ASSERT(!isDictionary()); + m_enumerationCache = enumerationCache; } } // namespace JSC diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h index 5eb0e4b..2542878 100644 --- a/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/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/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp index 91ddaeb..20ba868 100644 --- a/JavaScriptCore/runtime/JSString.cpp +++ b/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/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h index 1e46551..39dfe75 100644 --- a/JavaScriptCore/runtime/JSString.h +++ b/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/JavaScriptCore/runtime/JSTypeInfo.h b/JavaScriptCore/runtime/JSTypeInfo.h index 279510b..7c89600 100644 --- a/JavaScriptCore/runtime/JSTypeInfo.h +++ b/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/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h index 3c511d8..1063cdc 100644 --- a/JavaScriptCore/runtime/JSValue.h +++ b/JavaScriptCore/runtime/JSValue.h @@ -373,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()) diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h index 66e78c3..d8b1479 100644 --- a/JavaScriptCore/runtime/JSVariableObject.h +++ b/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/JavaScriptCore/runtime/JSWrapperObject.h b/JavaScriptCore/runtime/JSWrapperObject.h index 723b75d..191ff3b 100644 --- a/JavaScriptCore/runtime/JSWrapperObject.h +++ b/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/JavaScriptCore/runtime/MarkStack.h b/JavaScriptCore/runtime/MarkStack.h index ba00057..ea09f54 100644 --- a/JavaScriptCore/runtime/MarkStack.h +++ b/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/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h index fee5ec5..7f474b8 100644 --- a/JavaScriptCore/runtime/MathObject.h +++ b/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/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h index 908c55f..cf19b6f 100644 --- a/JavaScriptCore/runtime/NumberConstructor.h +++ b/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/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h index ca3923d..8223a90 100644 --- a/JavaScriptCore/runtime/NumberObject.h +++ b/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/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp index a456423..837d5a6 100644 --- a/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/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/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h index 5da9e38..1aa68b3 100644 --- a/JavaScriptCore/runtime/Operations.h +++ b/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/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp index 0878e73..c28b6a4 100644 --- a/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/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/JavaScriptCore/runtime/PropertyNameArray.h b/JavaScriptCore/runtime/PropertyNameArray.h index afcc83f..3dbcc9d 100644 --- a/JavaScriptCore/runtime/PropertyNameArray.h +++ b/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/JavaScriptCore/runtime/Protect.h b/JavaScriptCore/runtime/Protect.h index 224164d..a0d5443 100644 --- a/JavaScriptCore/runtime/Protect.h +++ b/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/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp index dbf2d44..c609e08 100644 --- a/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/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/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h index f8bccf4..f9ca9cf 100644 --- a/JavaScriptCore/runtime/RegExpConstructor.h +++ b/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/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp index 877d7b6..679d072 100644 --- a/JavaScriptCore/runtime/RegExpObject.cpp +++ b/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/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h index f5a9340..3117c86 100644 --- a/JavaScriptCore/runtime/RegExpObject.h +++ b/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/JavaScriptCore/runtime/StringObject.h b/JavaScriptCore/runtime/StringObject.h index 944f6ba..84e1ad2 100644 --- a/JavaScriptCore/runtime/StringObject.h +++ b/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/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index 0cba83d..69e1939 100644 --- a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/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/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp index b57732a..a0713b8 100644 --- a/JavaScriptCore/runtime/StringPrototype.cpp +++ b/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/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp index 7209b5f..65b62f9 100644 --- a/JavaScriptCore/runtime/Structure.cpp +++ b/JavaScriptCore/runtime/Structure.cpp @@ -28,9 +28,10 @@ #include "Identifier.h" #include "JSObject.h" +#include "JSPropertyNameIterator.h" +#include "Lookup.h" #include "PropertyNameArray.h" #include "StructureChain.h" -#include "Lookup.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/RefPtr.h> @@ -159,9 +160,9 @@ Structure::~Structure() m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); } - - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); + + if (m_enumerationCache) + m_enumerationCache->setCachedStructure(0); if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; @@ -282,59 +283,6 @@ void Structure::materializePropertyMap() } } -void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - getEnumerableNamesFromPropertyTable(propertyNames); - getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); -} - -void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); - - if (shouldCache && m_cachedPropertyNameArrayData) { - if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { - propertyNames.setData(m_cachedPropertyNameArrayData); - return; - } - clearEnumerationCache(); - } - - baseObject->getOwnPropertyNames(exec, propertyNames); - - if (m_prototype.isObject()) { - propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. - JSObject* prototype = asObject(m_prototype); - while(1) { - if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames); - break; - } - prototype->getOwnPropertyNames(exec, propertyNames); - JSValue nextProto = prototype->prototype(); - if (!nextProto.isObject()) - break; - prototype = asObject(nextProto); - } - } - - if (shouldCache) { - StructureChain* protoChain = prototypeChain(exec); - m_cachedPropertyNameArrayData = propertyNames.data(); - if (!protoChain->isCacheable()) - return; - m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain); - m_cachedPropertyNameArrayData->setCachedStructure(this); - } -} - -void Structure::clearEnumerationCache() -{ - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); - m_cachedPropertyNameArrayData.clear(); -} - void Structure::growPropertyStorageCapacity() { if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) @@ -427,6 +375,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_specificValueInPrevious = specificValue; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -469,6 +418,7 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -485,6 +435,7 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -516,6 +467,7 @@ PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structur transition->m_specificValueInPrevious = 0; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -544,6 +496,7 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo()); transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; // Don't set m_offset, as one can not transition to this. @@ -562,6 +515,7 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di transition->m_dictionaryKind = kind; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; + transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; structure->materializePropertyMapIfNecessary(); transition->m_propertyTable = structure->copyPropertyTable(); @@ -598,25 +552,28 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; + if (attributes & DontEnum) + m_hasNonEnumerableProperties = true; + size_t offset = put(propertyName, attributes, specificValue); if (propertyStorageSize() > propertyStorageCapacity()) growPropertyStorageCapacity(); - clearEnumerationCache(); return offset; } size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { ASSERT(isUncacheableDictionary()); + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = remove(propertyName); - clearEnumerationCache(); return offset; } @@ -1057,7 +1014,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b) return 0; } -void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames) +void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -1114,25 +1071,6 @@ void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyN } } -void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) -{ - // Add properties from the static hashtables of properties - for (; classInfo; classInfo = classInfo->parentClass) { - const HashTable* table = classInfo->propHashTable(exec); - if (!table) - continue; - table->initializeIfNeeded(exec); - ASSERT(table->table); - - int hashSizeMask = table->compactSize - 1; - const HashEntry* entry = table->table; - for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && !(entry->attributes() & DontEnum)) - propertyNames.add(entry->key()); - } - } -} - #if DO_PROPERTYMAP_CONSTENCY_CHECK void Structure::checkConsistency() diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h index ed9f6e5..f355c53 100644 --- a/JavaScriptCore/runtime/Structure.h +++ b/JavaScriptCore/runtime/Structure.h @@ -30,6 +30,8 @@ #include "JSType.h" #include "JSValue.h" #include "PropertyMapHashTable.h" +#include "PropertyNameArray.h" +#include "Protect.h" #include "StructureChain.h" #include "StructureTransitionTable.h" #include "JSTypeInfo.h" @@ -76,8 +78,6 @@ namespace JSC { ~Structure(); - void markAggregate(MarkStack&); - // These should be used with caution. size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t removePropertyWithoutTransition(const Identifier& propertyName); @@ -95,8 +95,8 @@ namespace JSC { Structure* previousID() const { return m_previous.get(); } void growPropertyStorageCapacity(); - size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; } - size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } + unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; } + unsigned propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } bool isUsingInlineStorage() const; size_t get(const Identifier& propertyName); @@ -116,17 +116,22 @@ namespace JSC { return hasTransition(propertyName._ustring.rep(), attributes); } - void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } + bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } + + bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; } + bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } JSCell* specificValue() { return m_specificValueInPrevious; } void despecifyDictionaryFunction(const Identifier& propertyName); + void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. + JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); } + void getEnumerablePropertyNames(PropertyNameArray&); + private: Structure(JSValue prototype, const TypeInfo&); @@ -140,8 +145,6 @@ namespace JSC { size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); void addAnonymousSlots(unsigned slotCount); - void getEnumerableNamesFromPropertyTable(PropertyNameArray&); - void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&); void expandPropertyMapHashTable(); void rehashPropertyMapHashTable(); @@ -162,8 +165,6 @@ namespace JSC { materializePropertyMap(); } - void clearEnumerationCache(); - signed char transitionCount() const { // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both. @@ -189,16 +190,17 @@ namespace JSC { StructureTransitionTable table; - RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; + ProtectedPtr<JSPropertyNameIterator> m_enumerationCache; PropertyMapHashTable* m_propertyTable; - size_t m_propertyStorageCapacity; + uint32_t m_propertyStorageCapacity; signed char m_offset; unsigned m_dictionaryKind : 2; bool m_isPinnedPropertyTable : 1; bool m_hasGetterSetterProperties : 1; + bool m_hasNonEnumerableProperties : 1; #if COMPILER(WINSCW) // Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared // bitfield, when used as argument in make_pair() function calls in structure.ccp. diff --git a/JavaScriptCore/runtime/StructureChain.cpp b/JavaScriptCore/runtime/StructureChain.cpp index 6e8a0ee..085876c 100644 --- a/JavaScriptCore/runtime/StructureChain.cpp +++ b/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/JavaScriptCore/runtime/StructureChain.h b/JavaScriptCore/runtime/StructureChain.h index c48749d..816b66d 100644 --- a/JavaScriptCore/runtime/StructureChain.h +++ b/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/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp index 45c724a..6751995 100644 --- a/JavaScriptCore/wtf/CurrentTime.cpp +++ b/JavaScriptCore/wtf/CurrentTime.cpp @@ -63,6 +63,10 @@ extern "C" time_t mktime(struct tm *t); #include <sys/time.h> #endif +#if PLATFORM(CHROMIUM) +#error Chromium uses a different timer implementation +#endif + namespace WTF { const double msPerSecond = 1000.0; diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp index 0386494..2110432 100644 --- a/JavaScriptCore/wtf/DateMath.cpp +++ b/JavaScriptCore/wtf/DateMath.cpp @@ -501,13 +501,13 @@ double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bo return result; } +// input is UTC void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) { - // input is UTC double dstOff = 0.0; - const double utcOff = getUTCOffset(); - - if (!outputIsUTC) { // convert to local time + double utcOff = 0.0; + if (!outputIsUTC) { + utcOff = getUTCOffset(); dstOff = getDSTOffset(ms, utcOff); ms += dstOff + utcOff; } @@ -522,8 +522,7 @@ void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; tm.isDST = dstOff != 0.0; - - tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond); + tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond); tm.timeZone = NULL; } diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h index ca0961c..541b05d 100644 --- a/JavaScriptCore/wtf/FastMalloc.h +++ b/JavaScriptCore/wtf/FastMalloc.h @@ -26,13 +26,19 @@ #include <stdlib.h> #include <new> +#if COMPILER(GCC) +#define WTF_FAST_MALLOC_EXPORT __attribute__((visibility("default"))) +#else +#define WTF_FAST_MALLOC_EXPORT +#endif + namespace WTF { // These functions call CRASH() if an allocation fails. - void* fastMalloc(size_t); + void* fastMalloc(size_t) WTF_FAST_MALLOC_EXPORT; void* fastZeroedMalloc(size_t); - void* fastCalloc(size_t numElements, size_t elementSize); - void* fastRealloc(void*, size_t); + void* fastCalloc(size_t numElements, size_t elementSize) WTF_FAST_MALLOC_EXPORT; + void* fastRealloc(void*, size_t) WTF_FAST_MALLOC_EXPORT; struct TryMallocReturnValue { TryMallocReturnValue(void* data) @@ -71,7 +77,7 @@ namespace WTF { TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size); TryMallocReturnValue tryFastRealloc(void* p, size_t n); - void fastFree(void*); + void fastFree(void*) WTF_FAST_MALLOC_EXPORT; #ifndef NDEBUG void fastMallocForbid(); diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h index 324300d..556230e 100644 --- a/JavaScriptCore/wtf/MathExtras.h +++ b/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/JavaScriptCore/wtf/MessageQueue.h b/JavaScriptCore/wtf/MessageQueue.h index 12291cc..9c9a4a78 100644 --- a/JavaScriptCore/wtf/MessageQueue.h +++ b/JavaScriptCore/wtf/MessageQueue.h @@ -55,9 +55,13 @@ namespace WTF { bool waitForMessage(DataType&); template<typename Predicate> MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime); - void kill(); + + template<typename Predicate> + void removeIf(Predicate&); bool tryGetMessage(DataType&); + + void kill(); bool killed() const; // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time. @@ -149,6 +153,17 @@ namespace WTF { } template<typename DataType> + template<typename Predicate> + inline void MessageQueue<DataType>::removeIf(Predicate& predicate) + { + MutexLocker lock(m_mutex); + DequeConstIterator<DataType> found = m_queue.end(); + while ((found = m_queue.findIf(predicate)) != m_queue.end()) { + m_queue.remove(found); + } + } + + template<typename DataType> inline bool MessageQueue<DataType>::isEmpty() { MutexLocker lock(m_mutex); diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 75a0bc4..cde4c17 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -493,6 +493,7 @@ #if PLATFORM(MAC) && !PLATFORM(IPHONE) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && defined(__x86_64__) #define WTF_USE_PLUGIN_HOST_PROCESS 1 #endif @@ -510,6 +511,7 @@ #if PLATFORM(CHROMIUM) && PLATFORM(DARWIN) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #if PLATFORM(IPHONE) @@ -526,6 +528,7 @@ #define HAVE_READLINE 1 #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #if PLATFORM(WIN) @@ -539,6 +542,7 @@ #if PLATFORM(GTK) #if HAVE(PTHREAD_H) #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #endif #endif @@ -546,6 +550,7 @@ #define HAVE_POSIX_MEMALIGN 1 #define WTF_USE_CURL 1 #define WTF_USE_PTHREADS 1 +#define HAVE_PTHREAD_RWLOCK 1 #define USE_SYSTEM_MALLOC 1 #define ENABLE_NETSCAPE_PLUGIN_API 0 #endif @@ -742,7 +747,7 @@ #endif #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) -#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX)) +#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX) || PLATFORM(WIN_OS)) #define WTF_USE_JSVALUE64 1 #elif PLATFORM(ARM) || PLATFORM(PPC64) #define WTF_USE_JSVALUE32 1 @@ -769,8 +774,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 #elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) - /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ - #define ENABLE_JIT 0 + #define ENABLE_JIT 1 #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 /* The JIT is tested & working on x86 Windows */ #elif PLATFORM(X86) && PLATFORM(WIN) @@ -836,8 +840,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */ #if (PLATFORM(X86) && PLATFORM(MAC)) \ || (PLATFORM(X86_64) && PLATFORM(MAC)) \ - /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \ - || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) && 0) \ + || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE)) \ || (PLATFORM(X86) && PLATFORM(WIN)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 @@ -903,6 +906,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/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h index d21d1ff..c9b5742 100644 --- a/JavaScriptCore/wtf/StdLibExtras.h +++ b/JavaScriptCore/wtf/StdLibExtras.h @@ -32,6 +32,7 @@ // Use these to declare and define a static local variable (static T;) so that // it is leaked so that its destructors are not called at exit. Using this // macro also allows workarounds a compiler bug present in Apple's version of GCC 4.0.1. +#ifndef DEFINE_STATIC_LOCAL #if COMPILER(GCC) && defined(__APPLE_CC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 1 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ static type* name##Ptr = new type arguments; \ @@ -40,6 +41,7 @@ #define DEFINE_STATIC_LOCAL(type, name, arguments) \ static type& name = *new type arguments #endif +#endif // OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes. // The magic number 0x4000 is insignificant. We use it to avoid using NULL, since diff --git a/JavaScriptCore/wtf/StringExtras.h b/JavaScriptCore/wtf/StringExtras.h index 559e3f2..1120d65 100644 --- a/JavaScriptCore/wtf/StringExtras.h +++ b/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/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp index 56bf438..1d4185c 100644 --- a/JavaScriptCore/wtf/Threading.cpp +++ b/JavaScriptCore/wtf/Threading.cpp @@ -51,7 +51,7 @@ static void* threadEntryPoint(void* contextData) setThreadNameInternal(context->name); - // Block until our creating thread has completed any extra setup work + // Block until our creating thread has completed any extra setup work. { MutexLocker locker(context->creationMutex); } diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp index abefb40..38faa61 100644 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -272,7 +272,10 @@ void Mutex::unlock() } #if HAVE(PTHREAD_RWLOCK) +<<<<<<< HEAD:JavaScriptCore/wtf/ThreadingPthreads.cpp +======= +>>>>>>> webkit.org at r50258.:JavaScriptCore/wtf/ThreadingPthreads.cpp ReadWriteLock::ReadWriteLock() { pthread_rwlock_init(&m_readWriteLock, NULL); diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp index aafea3c..d088086 100644 --- a/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -1490,7 +1490,7 @@ public: closeBodyAlternative(); } - void alterantiveBodyDisjunction() + void alternativeBodyDisjunction() { int newAlternativeIndex = m_bodyDisjunction->terms.size(); m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; @@ -1499,7 +1499,7 @@ public: m_currentAlternativeIndex = newAlternativeIndex; } - void alterantiveDisjunction() + void alternativeDisjunction() { int newAlternativeIndex = m_bodyDisjunction->terms.size(); m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex; @@ -1515,9 +1515,9 @@ public: if (alt) { if (disjunction == m_pattern.m_body) - alterantiveBodyDisjunction(); + alternativeBodyDisjunction(); else - alterantiveDisjunction(); + alternativeDisjunction(); } PatternAlternative* alternative = disjunction->m_alternatives[alt]; diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp index d777424..5ce579a 100644 --- a/JavaScriptCore/yarr/RegexJIT.cpp +++ b/JavaScriptCore/yarr/RegexJIT.cpp @@ -1264,7 +1264,7 @@ class RegexGenerator : private MacroAssembler { // complex here in compilation, and in the common case we should end up coallescing the checks. // // FIXME: a nice improvement here may be to stop trying to match sooner, based on the least - // of the minimum-alterantive-lengths. E.g. if I have two alternatives of length 200 and 150, + // of the minimum-alternative-lengths. E.g. if I have two alternatives of length 200 and 150, // and a string of length 100, we'll end up looping index from 0 to 100, checking whether there // is sufficient input to run either alternative (constantly failing). If there had been only // one alternative, or if the shorter alternative had come first, we would have terminated @@ -1309,9 +1309,6 @@ class RegexGenerator : private MacroAssembler { loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif #elif PLATFORM(ARM) -#if PLATFORM(ARM_TRADITIONAL) - push(ARMRegisters::lr); -#endif push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); @@ -1400,14 +1397,6 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const } } -int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize) -{ - if (JSRegExp* fallback = jitObject.getFallback()) - return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0]; - - return jitObject.execute(input, start, length, output); -} - }} #endif diff --git a/JavaScriptCore/yarr/RegexJIT.h b/JavaScriptCore/yarr/RegexJIT.h index 5b0df9d..1872f21 100644 --- a/JavaScriptCore/yarr/RegexJIT.h +++ b/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 |